merge the last green changeset on m-c to fx-team
|
@ -55,7 +55,7 @@
|
|||
NotificationController::NotificationController(nsDocAccessible* aDocument,
|
||||
nsIPresShell* aPresShell) :
|
||||
mObservingState(eNotObservingRefresh), mDocument(aDocument),
|
||||
mPresShell(aPresShell), mTreeConstructedState(eTreeConstructionPending)
|
||||
mPresShell(aPresShell)
|
||||
{
|
||||
mTextHash.Init();
|
||||
|
||||
|
@ -154,10 +154,6 @@ NotificationController::ScheduleContentInsertion(nsAccessible* aContainer,
|
|||
nsIContent* aStartChildNode,
|
||||
nsIContent* aEndChildNode)
|
||||
{
|
||||
// Ignore content insertions until we constructed accessible tree.
|
||||
if (mTreeConstructedState == eTreeConstructionPending)
|
||||
return;
|
||||
|
||||
nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
|
||||
aContainer);
|
||||
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
|
||||
|
@ -207,7 +203,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
mObservingState = eRefreshProcessingForUpdate;
|
||||
|
||||
// Initial accessible tree construction.
|
||||
if (mTreeConstructedState == eTreeConstructionPending) {
|
||||
if (!mDocument->HasLoadState(nsDocAccessible::eTreeConstructed)) {
|
||||
// If document is not bound to parent at this point then the document is not
|
||||
// ready yet (process notifications later).
|
||||
if (!mDocument->IsBoundToParent())
|
||||
|
@ -218,8 +214,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
mDocument.get(), mDocument->GetDocumentNode());
|
||||
#endif
|
||||
|
||||
mTreeConstructedState = eTreeConstructed;
|
||||
mDocument->NotifyOfInitialUpdate();
|
||||
mDocument->DoInitialUpdate();
|
||||
|
||||
NS_ASSERTION(mContentInsertions.Length() == 0,
|
||||
"Pending content insertions while initial accessible tree isn't created!");
|
||||
|
@ -250,8 +245,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
mTextHash.Clear();
|
||||
|
||||
// Bind hanging child documents.
|
||||
PRUint32 childDocCount = mHangingChildDocuments.Length();
|
||||
for (PRUint32 idx = 0; idx < childDocCount; idx++) {
|
||||
PRUint32 hangingDocCnt = mHangingChildDocuments.Length();
|
||||
for (PRUint32 idx = 0; idx < hangingDocCnt; idx++) {
|
||||
nsDocAccessible* childDoc = mHangingChildDocuments[idx];
|
||||
|
||||
nsIContent* ownerContent = mDocument->GetDocumentNode()->
|
||||
|
@ -271,6 +266,25 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
}
|
||||
mHangingChildDocuments.Clear();
|
||||
|
||||
// If the document is ready and all its subdocuments are completely loaded
|
||||
// then process the document load.
|
||||
if (mDocument->HasLoadState(nsDocAccessible::eReady) &&
|
||||
!mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
|
||||
hangingDocCnt == 0) {
|
||||
PRUint32 childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0;
|
||||
for (; childDocIdx < childDocCnt; childDocIdx++) {
|
||||
nsDocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx);
|
||||
if (!childDoc->HasLoadState(nsDocAccessible::eCompletelyLoaded))
|
||||
break;
|
||||
}
|
||||
|
||||
if (childDocIdx == childDocCnt) {
|
||||
mDocument->ProcessLoad();
|
||||
if (!mDocument)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Process only currently queued generic notifications.
|
||||
nsTArray < nsRefPtr<Notification> > notifications;
|
||||
notifications.SwapElements(mNotifications);
|
||||
|
@ -310,10 +324,12 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
return;
|
||||
}
|
||||
|
||||
// Stop further processing if there are no newly queued insertions,
|
||||
// notifications or events.
|
||||
// Stop further processing if there are no new notifications of any kind or
|
||||
// events and document load is processed.
|
||||
if (mContentInsertions.Length() == 0 && mNotifications.Length() == 0 &&
|
||||
mEvents.Length() == 0 &&
|
||||
mEvents.Length() == 0 && mTextHash.Count() == 0 &&
|
||||
mHangingChildDocuments.Length() == 0 &&
|
||||
mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
|
||||
mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
|
||||
mObservingState = eNotObservingRefresh;
|
||||
}
|
||||
|
|
|
@ -127,14 +127,6 @@ public:
|
|||
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
|
||||
|
||||
/**
|
||||
* Return true when tree is constructed.
|
||||
*/
|
||||
inline bool IsTreeConstructed()
|
||||
{
|
||||
return mTreeConstructedState == eTreeConstructed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the notification controller.
|
||||
*/
|
||||
|
@ -155,11 +147,8 @@ public:
|
|||
*/
|
||||
inline void ScheduleTextUpdate(nsIContent* aTextNode)
|
||||
{
|
||||
// Ignore the notification if initial tree construction hasn't been done yet.
|
||||
if (mTreeConstructedState != eTreeConstructionPending &&
|
||||
mTextHash.PutEntry(aTextNode)) {
|
||||
if (mTextHash.PutEntry(aTextNode))
|
||||
ScheduleProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,17 +288,6 @@ private:
|
|||
*/
|
||||
nsIPresShell* mPresShell;
|
||||
|
||||
/**
|
||||
* Indicate whether initial construction of the document's accessible tree
|
||||
* performed or pending. When the document accessible is created then
|
||||
* we construct its initial accessible tree.
|
||||
*/
|
||||
enum eTreeConstructedState {
|
||||
eTreeConstructed,
|
||||
eTreeConstructionPending
|
||||
};
|
||||
eTreeConstructedState mTreeConstructedState;
|
||||
|
||||
/**
|
||||
* Child documents that needs to be bound to the tree.
|
||||
*/
|
||||
|
|
|
@ -190,9 +190,6 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
|||
NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest,
|
||||
aStateFlags)
|
||||
|
||||
if (!IsEventTargetDocument(document))
|
||||
return NS_OK;
|
||||
|
||||
nsDocAccessible* docAcc = mDocAccessibleCache.GetWeak(document);
|
||||
if (!docAcc)
|
||||
return NS_OK;
|
||||
|
@ -201,32 +198,17 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
|||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
|
||||
NS_ENSURE_STATE(docShell);
|
||||
|
||||
// Fire reload and state busy events on existing document accessible while
|
||||
// event from user input flag can be calculated properly and accessible
|
||||
// is alive. When new document gets loaded then this one is destroyed.
|
||||
bool isReloading = false;
|
||||
PRUint32 loadType;
|
||||
docShell->GetLoadType(&loadType);
|
||||
if (loadType == LOAD_RELOAD_NORMAL ||
|
||||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
|
||||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
|
||||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
|
||||
|
||||
// Fire reload event.
|
||||
nsRefPtr<AccEvent> reloadEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc);
|
||||
nsEventShell::FireEvent(reloadEvent);
|
||||
isReloading = true;
|
||||
}
|
||||
|
||||
// Mark the document accessible as loading, if it stays alive then we'll mark
|
||||
// it as loaded when we receive proper notification.
|
||||
docAcc->MarkAsLoading();
|
||||
|
||||
// Fire state busy change event. Use delayed event since we don't care
|
||||
// actually if event isn't delivered when the document goes away like a shot.
|
||||
nsRefPtr<AccEvent> stateEvent =
|
||||
new AccStateChangeEvent(document, states::BUSY, PR_TRUE);
|
||||
docAcc->FireDelayedAccessibleEvent(stateEvent);
|
||||
|
||||
docAcc->NotifyOfLoading(isReloading);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -338,54 +320,7 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
|
|||
return;
|
||||
}
|
||||
|
||||
// Mark the document as loaded to drop off the busy state flag on it.
|
||||
docAcc->MarkAsLoaded();
|
||||
|
||||
// Do not fire document complete/stop events for root chrome document
|
||||
// accessibles and for frame/iframe documents because
|
||||
// a) screen readers start working on focus event in the case of root chrome
|
||||
// documents
|
||||
// b) document load event on sub documents causes screen readers to act is if
|
||||
// entire page is reloaded.
|
||||
if (!IsEventTargetDocument(aDocument))
|
||||
return;
|
||||
|
||||
// Fire complete/load stopped if the load event type is given.
|
||||
if (aLoadEventType) {
|
||||
nsRefPtr<AccEvent> loadEvent = new AccEvent(aLoadEventType, aDocument);
|
||||
docAcc->FireDelayedAccessibleEvent(loadEvent);
|
||||
}
|
||||
|
||||
// Fire busy state change event.
|
||||
nsRefPtr<AccEvent> stateEvent =
|
||||
new AccStateChangeEvent(aDocument, states::BUSY, PR_FALSE);
|
||||
docAcc->FireDelayedAccessibleEvent(stateEvent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const
|
||||
{
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
do_QueryInterface(container);
|
||||
NS_ASSERTION(docShellTreeItem, "No document shell for document!");
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
|
||||
docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
|
||||
|
||||
// It's not a root document.
|
||||
if (parentTreeItem) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
|
||||
// It's not a sub document, i.e. a frame or iframe.
|
||||
return (sameTypeRoot == docShellTreeItem);
|
||||
}
|
||||
|
||||
// It's not chrome root document.
|
||||
PRInt32 contentType;
|
||||
docShellTreeItem->GetItemType(&contentType);
|
||||
return (contentType == nsIDocShellTreeItem::typeContent);
|
||||
docAcc->NotifyOfLoad(aLoadEventType);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -120,24 +120,6 @@ private:
|
|||
void HandleDOMDocumentLoad(nsIDocument *aDocument,
|
||||
PRUint32 aLoadEventType);
|
||||
|
||||
/**
|
||||
* Return true if accessibility events accompanying document accessible
|
||||
* loading should be fired.
|
||||
*
|
||||
* The rules are: do not fire events for root chrome document accessibles and
|
||||
* for sub document accessibles (like HTML frame of iframe) of the loading
|
||||
* document accessible.
|
||||
*
|
||||
* XXX: in general AT expect events for document accessible loading into
|
||||
* tabbrowser, events from other document accessibles may break AT. We need to
|
||||
* figure out what AT wants to know about loading page (for example, some of
|
||||
* them have separate processing of iframe documents on the page and therefore
|
||||
* they need a way to distinguish sub documents from page document). Ideally
|
||||
* we should make events firing for any loaded document and provide additional
|
||||
* info AT are needing.
|
||||
*/
|
||||
PRBool IsEventTargetDocument(nsIDocument *aDocument) const;
|
||||
|
||||
/**
|
||||
* Add 'pagehide' and 'DOMContentLoaded' event listeners.
|
||||
*/
|
||||
|
|
|
@ -105,7 +105,8 @@ nsDocAccessible::
|
|||
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||
nsIWeakReference *aShell) :
|
||||
nsHyperTextAccessibleWrap(aRootContent, aShell),
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0),
|
||||
mLoadState(eTreeConstructionPending), mLoadEventType(0)
|
||||
{
|
||||
mFlags |= eDocAccessible;
|
||||
|
||||
|
@ -309,11 +310,16 @@ nsDocAccessible::NativeState()
|
|||
state |= states::FOCUSED;
|
||||
}
|
||||
|
||||
// Expose state busy until the document is loaded or tree is constructed.
|
||||
if (!mIsLoaded || !mNotificationController->IsTreeConstructed()) {
|
||||
state |= states::BUSY | states::STALE;
|
||||
}
|
||||
|
||||
// Expose stale state until the document is ready (DOM is loaded and tree is
|
||||
// constructed).
|
||||
if (!HasLoadState(eReady))
|
||||
state |= states::STALE;
|
||||
|
||||
// Expose state busy until the document and all its subdocuments is completely
|
||||
// loaded.
|
||||
if (!HasLoadState(eCompletelyLoaded))
|
||||
state |= states::BUSY;
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame || !nsCoreUtils::CheckVisibilityInParentChain(frame)) {
|
||||
state |= states::INVISIBLE | states::OFFSCREEN;
|
||||
|
@ -605,7 +611,7 @@ nsDocAccessible::Init()
|
|||
// this point (this can happen because a11y is started late or DOM document
|
||||
// having no container was loaded.
|
||||
if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE)
|
||||
mIsLoaded = PR_TRUE;
|
||||
mLoadState |= eDOMLoaded;
|
||||
|
||||
AddEventListeners();
|
||||
return PR_TRUE;
|
||||
|
@ -1376,8 +1382,9 @@ nsDocAccessible::ContentInserted(nsIContent* aContainerNode,
|
|||
nsIContent* aStartChildNode,
|
||||
nsIContent* aEndChildNode)
|
||||
{
|
||||
/// Pend tree update on content insertion until layout.
|
||||
if (mNotificationController) {
|
||||
// Ignore content insertions until we constructed accessible tree. Otherwise
|
||||
// schedule tree update on content insertion after layout.
|
||||
if (mNotificationController && HasLoadState(eTreeConstructed)) {
|
||||
// Update the whole tree of this document accessible when the container is
|
||||
// null (document element is inserted or removed).
|
||||
nsAccessible* container = aContainerNode ?
|
||||
|
@ -1467,8 +1474,36 @@ nsDocAccessible::CacheChildren()
|
|||
// Protected members
|
||||
|
||||
void
|
||||
nsDocAccessible::NotifyOfInitialUpdate()
|
||||
nsDocAccessible::NotifyOfLoading(bool aIsReloading)
|
||||
{
|
||||
// Mark the document accessible as loading, if it stays alive then we'll mark
|
||||
// it as loaded when we receive proper notification.
|
||||
mLoadState &= ~eDOMLoaded;
|
||||
|
||||
if (!IsLoadEventTarget())
|
||||
return;
|
||||
|
||||
if (aIsReloading) {
|
||||
// Fire reload and state busy events on existing document accessible while
|
||||
// event from user input flag can be calculated properly and accessible
|
||||
// is alive. When new document gets loaded then this one is destroyed.
|
||||
nsRefPtr<AccEvent> reloadEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, this);
|
||||
nsEventShell::FireEvent(reloadEvent);
|
||||
}
|
||||
|
||||
// Fire state busy change event. Use delayed event since we don't care
|
||||
// actually if event isn't delivered when the document goes away like a shot.
|
||||
nsRefPtr<AccEvent> stateEvent =
|
||||
new AccStateChangeEvent(mDocument, states::BUSY, PR_TRUE);
|
||||
FireDelayedAccessibleEvent(stateEvent);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::DoInitialUpdate()
|
||||
{
|
||||
mLoadState |= eTreeConstructed;
|
||||
|
||||
// The content element may be changed before the initial update and then we
|
||||
// miss the notification (since content tree change notifications are ignored
|
||||
// prior to initial update). Make sure the content element is valid.
|
||||
|
@ -1491,6 +1526,34 @@ nsDocAccessible::NotifyOfInitialUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::ProcessLoad()
|
||||
{
|
||||
mLoadState |= eCompletelyLoaded;
|
||||
|
||||
// Do not fire document complete/stop events for root chrome document
|
||||
// accessibles and for frame/iframe documents because
|
||||
// a) screen readers start working on focus event in the case of root chrome
|
||||
// documents
|
||||
// b) document load event on sub documents causes screen readers to act is if
|
||||
// entire page is reloaded.
|
||||
if (!IsLoadEventTarget())
|
||||
return;
|
||||
|
||||
// Fire complete/load stopped if the load event type is given.
|
||||
if (mLoadEventType) {
|
||||
nsRefPtr<AccEvent> loadEvent = new AccEvent(mLoadEventType, this);
|
||||
nsEventShell::FireEvent(loadEvent);
|
||||
|
||||
mLoadEventType = 0;
|
||||
}
|
||||
|
||||
// Fire busy state change event.
|
||||
nsRefPtr<AccEvent> stateEvent =
|
||||
new AccStateChangeEvent(this, states::BUSY, PR_FALSE);
|
||||
nsEventShell::FireEvent(stateEvent);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
|
||||
nsIAtom* aRelAttr)
|
||||
|
@ -1964,3 +2027,30 @@ nsDocAccessible::ShutdownChildrenInSubtree(nsAccessible* aAccessible)
|
|||
|
||||
UnbindFromDocument(aAccessible);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocAccessible::IsLoadEventTarget() const
|
||||
{
|
||||
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
do_QueryInterface(container);
|
||||
NS_ASSERTION(docShellTreeItem, "No document shell for document!");
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
|
||||
docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
|
||||
|
||||
// It's not a root document.
|
||||
if (parentTreeItem) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
|
||||
// It's not a sub document, i.e. a frame or iframe.
|
||||
return (sameTypeRoot == docShellTreeItem);
|
||||
}
|
||||
|
||||
// It's not chrome root document.
|
||||
PRInt32 contentType;
|
||||
docShellTreeItem->GetItemType(&contentType);
|
||||
return (contentType == nsIDocShellTreeItem::typeContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,19 +134,34 @@ public:
|
|||
*/
|
||||
PRBool IsContentLoaded() const
|
||||
{
|
||||
// eDOMLoaded flag check is used for error pages as workaround to make this
|
||||
// method return correct result since error pages do not receive 'pageshow'
|
||||
// event and as consequence nsIDocument::IsShowing() returns false.
|
||||
return mDocument && mDocument->IsVisible() &&
|
||||
(mDocument->IsShowing() || mIsLoaded);
|
||||
(mDocument->IsShowing() || HasLoadState(eDOMLoaded));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this document as loaded or loading, used to expose busy state.
|
||||
* The loaded flag has special meaning for error pages and used as workaround
|
||||
* to make IsContentLoaded() return correct result since these pages do not
|
||||
* receive pageshow event and as consequence nsIDocument::IsShowing() returns
|
||||
* false.
|
||||
* Document load states.
|
||||
*/
|
||||
void MarkAsLoaded() { mIsLoaded = PR_TRUE; }
|
||||
void MarkAsLoading() { mIsLoaded = PR_FALSE; }
|
||||
enum LoadState {
|
||||
// initial tree construction is pending
|
||||
eTreeConstructionPending = 0,
|
||||
// initial tree construction done
|
||||
eTreeConstructed = 1,
|
||||
// DOM document is loaded.
|
||||
eDOMLoaded = 1 << 1,
|
||||
// document is ready
|
||||
eReady = eTreeConstructed | eDOMLoaded,
|
||||
// document and all its subdocuments are ready
|
||||
eCompletelyLoaded = eReady | 1 << 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the document has given document state.
|
||||
*/
|
||||
bool HasLoadState(LoadState aState) const
|
||||
{ return (mLoadState & aState) == aState; }
|
||||
|
||||
/**
|
||||
* Return a native window handler or pointer depending on platform.
|
||||
|
@ -326,7 +341,8 @@ public:
|
|||
{
|
||||
NS_ASSERTION(mNotificationController, "The document was shut down!");
|
||||
|
||||
if (mNotificationController)
|
||||
// Ignore the notification if initial tree construction hasn't been done yet.
|
||||
if (mNotificationController && HasLoadState(eTreeConstructed))
|
||||
mNotificationController->ScheduleTextUpdate(aTextNode);
|
||||
}
|
||||
|
||||
|
@ -346,10 +362,29 @@ protected:
|
|||
virtual nsresult RemoveEventListeners();
|
||||
|
||||
/**
|
||||
* Notify this document that was bound to the accessible document tree.
|
||||
* Marks this document as loaded or loading.
|
||||
*/
|
||||
inline void NotifyOfLoad(PRUint32 aLoadEventType)
|
||||
{
|
||||
mLoadState |= eDOMLoaded;
|
||||
mLoadEventType = aLoadEventType;
|
||||
}
|
||||
|
||||
void NotifyOfLoading(bool aIsReloading);
|
||||
|
||||
friend class nsAccDocManager;
|
||||
|
||||
/**
|
||||
* Perform initial update (create accessible tree).
|
||||
* Can be overridden by wrappers to prepare initialization work.
|
||||
*/
|
||||
virtual void NotifyOfInitialUpdate();
|
||||
virtual void DoInitialUpdate();
|
||||
|
||||
/**
|
||||
* Process document load notification, fire document load and state busy
|
||||
* events if applicable.
|
||||
*/
|
||||
void ProcessLoad();
|
||||
|
||||
void AddScrollListener();
|
||||
void RemoveScrollListener();
|
||||
|
@ -483,6 +518,24 @@ protected:
|
|||
*/
|
||||
void ShutdownChildrenInSubtree(nsAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Return true if accessibility events accompanying document accessible
|
||||
* loading should be fired.
|
||||
*
|
||||
* The rules are: do not fire events for root chrome document accessibles and
|
||||
* for sub document accessibles (like HTML frame of iframe) of the loading
|
||||
* document accessible.
|
||||
*
|
||||
* XXX: in general AT expect events for document accessible loading into
|
||||
* tabbrowser, events from other document accessibles may break AT. We need to
|
||||
* figure out what AT wants to know about loading page (for example, some of
|
||||
* them have separate processing of iframe documents on the page and therefore
|
||||
* they need a way to distinguish sub documents from page document). Ideally
|
||||
* we should make events firing for any loaded document and provide additional
|
||||
* info AT are needing.
|
||||
*/
|
||||
bool IsLoadEventTarget() const;
|
||||
|
||||
/**
|
||||
* Used to fire scrolling end event after page scroll.
|
||||
*
|
||||
|
@ -491,6 +544,8 @@ protected:
|
|||
*/
|
||||
static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Cache of accessibles within this document accessible.
|
||||
*/
|
||||
|
@ -502,12 +557,15 @@ protected:
|
|||
nsCOMPtr<nsITimer> mScrollWatchTimer;
|
||||
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Bit mask of document load states (@see LoadState).
|
||||
*/
|
||||
PRUint32 mLoadState;
|
||||
|
||||
/**
|
||||
* Specifies if the document was loaded, used for error pages only.
|
||||
* Type of document load event fired after the document is loaded completely.
|
||||
*/
|
||||
PRPackedBool mIsLoaded;
|
||||
PRUint32 mLoadEventType;
|
||||
|
||||
static PRUint64 gLastFocusedAccessiblesState;
|
||||
|
||||
|
|
|
@ -49,8 +49,7 @@
|
|||
#include "nsHashtable.h"
|
||||
#include "nsCaretAccessible.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
#define NS_ROOTACCESSIBLE_IMPL_CID \
|
||||
{ /* eaba2cf0-21b1-4e2b-b711-d3a89dcd5e1a */ \
|
||||
|
|
|
@ -268,9 +268,9 @@ nsDocAccessibleWrap::GetNativeWindow() const
|
|||
// nsDocAccessible protected
|
||||
|
||||
void
|
||||
nsDocAccessibleWrap::NotifyOfInitialUpdate()
|
||||
nsDocAccessibleWrap::DoInitialUpdate()
|
||||
{
|
||||
nsDocAccessible::NotifyOfInitialUpdate();
|
||||
nsDocAccessible::DoInitialUpdate();
|
||||
|
||||
if (nsWinUtils::IsWindowEmulationStarted()) {
|
||||
// Create window for tab document.
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
|
||||
protected:
|
||||
// nsDocAccessible
|
||||
virtual void NotifyOfInitialUpdate();
|
||||
virtual void DoInitialUpdate();
|
||||
|
||||
protected:
|
||||
void* mHWND;
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
|
||||
if (this.reorderCnt == docURIs.length) {
|
||||
unregisterA11yEventListener(EVENT_REORDER, this);
|
||||
testAccTree();
|
||||
testRelations();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
<menuseparator id="page-menu-separator"/>
|
||||
<menuitem id="spell-no-suggestions"
|
||||
disabled="true"
|
||||
label="&spellNoSuggestions.label;"/>
|
||||
|
|
|
@ -216,6 +216,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
|
|||
"nsICrashReporter");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
|
||||
return new tmp.PageMenu();
|
||||
});
|
||||
|
||||
/**
|
||||
* We can avoid adding multiple load event listeners and save some time by adding
|
||||
* one listener that calls all real handlers.
|
||||
|
|
|
@ -273,10 +273,10 @@
|
|||
oncommand="BrowserFullScreen();"/>
|
||||
</menupopup>
|
||||
|
||||
<menupopup id="contentAreaContextMenu"
|
||||
<menupopup id="contentAreaContextMenu" pagemenu="start"
|
||||
onpopupshowing="if (event.target != this)
|
||||
return true;
|
||||
gContextMenu = new nsContextMenu(this, gBrowser);
|
||||
gContextMenu = new nsContextMenu(this, gBrowser, event.shiftKey);
|
||||
if (gContextMenu.shouldDisplay)
|
||||
updateEditUIVisibility();
|
||||
return gContextMenu.shouldDisplay;"
|
||||
|
@ -1009,7 +1009,7 @@
|
|||
<svg:svg height="0">
|
||||
<svg:mask id="pinstripe-keyhole-forward-mask" maskContentUnits="objectBoundingBox">
|
||||
<svg:rect x="0" y="0" width="1" height="1" fill="white"/>
|
||||
<svg:circle cx="-0.46" cy="0.48" r="0.65"/>
|
||||
<svg:circle cx="-0.41" cy="0.5" r="0.65"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-tab-ontop-left-curve-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:circle cx="9" cy="3" r="3" fill="white"/>
|
||||
|
|
|
@ -61,14 +61,14 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
function nsContextMenu(aXulMenu, aBrowser) {
|
||||
function nsContextMenu(aXulMenu, aBrowser, aIsShift) {
|
||||
this.shouldDisplay = true;
|
||||
this.initMenu(aBrowser);
|
||||
this.initMenu(aBrowser, aXulMenu, aIsShift);
|
||||
}
|
||||
|
||||
// Prototype for nsContextMenu "class."
|
||||
nsContextMenu.prototype = {
|
||||
initMenu: function CM_initMenu(aBrowser) {
|
||||
initMenu: function CM_initMenu(aBrowser, aXulMenu, aIsShift) {
|
||||
// Get contextual info.
|
||||
this.setTarget(document.popupNode, document.popupRangeParent,
|
||||
document.popupRangeOffset);
|
||||
|
@ -76,6 +76,12 @@ nsContextMenu.prototype = {
|
|||
return;
|
||||
|
||||
this.browser = aBrowser;
|
||||
|
||||
this.hasPageMenu = false;
|
||||
if (!aIsShift) {
|
||||
this.hasPageMenu = PageMenu.init(this.target, aXulMenu);
|
||||
}
|
||||
|
||||
this.isFrameImage = document.getElementById("isFrameImage");
|
||||
this.ellipsis = "\u2026";
|
||||
try {
|
||||
|
@ -90,6 +96,7 @@ nsContextMenu.prototype = {
|
|||
},
|
||||
|
||||
initItems: function CM_initItems() {
|
||||
this.initPageMenuSeparator();
|
||||
this.initOpenItems();
|
||||
this.initNavigationItems();
|
||||
this.initViewItems();
|
||||
|
@ -100,6 +107,10 @@ nsContextMenu.prototype = {
|
|||
this.initMediaPlayerItems();
|
||||
},
|
||||
|
||||
initPageMenuSeparator: function CM_initPageMenuSeparator() {
|
||||
this.showItem("page-menu-separator", this.hasPageMenu);
|
||||
},
|
||||
|
||||
initOpenItems: function CM_initOpenItems() {
|
||||
var isMailtoInternal = false;
|
||||
if (this.onMailtoLink) {
|
||||
|
|
|
@ -21,6 +21,40 @@ Browser context menu subtest.
|
|||
<textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
|
||||
<div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
|
||||
<input id="test-input-spellcheck" type="text" spellcheck="true" autofocus value="prodkjfgigrty"> <!-- this one also generates one suggestion -->
|
||||
<div contextmenu="myMenu">
|
||||
<p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
|
||||
<menu id="myMenu" type="context">
|
||||
<menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
|
||||
<menuitem label="Disabled item" disabled></menuitem>
|
||||
<menu>
|
||||
<menuitem type="checkbox" label="Checkbox" checked></menuitem>
|
||||
</menu>
|
||||
<menu>
|
||||
<menuitem type="radio" label="Radio1" checked></menuitem>
|
||||
<menuitem type="radio" label="Radio2"></menuitem>
|
||||
<menuitem type="radio" label="Radio3"></menuitem>
|
||||
</menu>
|
||||
<menu>
|
||||
<menuitem label="Item w/ icon" icon="favicon.ico"></menuitem>
|
||||
<menuitem label="Item w/ bad icon" icon="data://www.mozilla.org/favicon.ico"></menuitem>
|
||||
</menu>
|
||||
<menu label="Submenu">
|
||||
<menuitem type="radio" label="Radio1" radiogroup="rg"></menuitem>
|
||||
<menuitem type="radio" label="Radio2" checked radiogroup="rg"></menuitem>
|
||||
<menuitem type="radio" label="Radio3" radiogroup="rg"></menuitem>
|
||||
<menu>
|
||||
<menuitem type="checkbox" label="Checkbox"></menuitem>
|
||||
</menu>
|
||||
</menu>
|
||||
<menu hidden>
|
||||
<menuitem label="Bogus item"></menuitem>
|
||||
</menu>
|
||||
<menu>
|
||||
</menu>
|
||||
<menuitem label="Hidden item" hidden></menuitem>
|
||||
<menuitem></menuitem>
|
||||
</menu>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -24,11 +24,11 @@ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function openContextMenuFor(element) {
|
||||
function openContextMenuFor(element, shiftkey) {
|
||||
// Context menu should be closed before we open it again.
|
||||
is(contextMenu.state, "closed", "checking if popup is closed");
|
||||
|
||||
var eventDetails = { type : "contextmenu", button : 2 };
|
||||
var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
|
||||
synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,15 @@ function executeCopyCommand(command, expectedValue)
|
|||
is(input.value, expectedValue, "paste for command " + command);
|
||||
}
|
||||
|
||||
function getVisibleMenuItems(aMenu) {
|
||||
function invokeItemAction(ident)
|
||||
{
|
||||
var item = contextMenu.getElementsByAttribute("ident", ident)[0];
|
||||
ok(item, "Got generated XUL menu item");
|
||||
item.doCommand();
|
||||
is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
|
||||
}
|
||||
|
||||
function getVisibleMenuItems(aMenu, aData) {
|
||||
var items = [];
|
||||
var accessKeys = {};
|
||||
for (var i = 0; i < aMenu.childNodes.length; i++) {
|
||||
|
@ -62,10 +70,14 @@ function getVisibleMenuItems(aMenu) {
|
|||
if (key)
|
||||
key = key.toLowerCase();
|
||||
|
||||
var isGenerated = item.hasAttribute("generated");
|
||||
|
||||
if (item.nodeName == "menuitem") {
|
||||
var isSpellSuggestion = item.className == "spell-suggestion";
|
||||
if (isSpellSuggestion) {
|
||||
is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
|
||||
} else if (isGenerated) {
|
||||
is(item.id, "", "child menuitem #" + i + " is a generated item");
|
||||
} else {
|
||||
ok(item.id, "child menuitem #" + i + " has an ID");
|
||||
}
|
||||
|
@ -74,6 +86,8 @@ function getVisibleMenuItems(aMenu) {
|
|||
if (isSpellSuggestion) {
|
||||
is(key, "", "Spell suggestions shouldn't have an access key");
|
||||
items.push("*" + label);
|
||||
} else if (isGenerated) {
|
||||
items.push("+" + label);
|
||||
} else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
|
||||
item.id != "spell-no-suggestions") {
|
||||
ok(key, "menuitem " + item.id + " has an access key");
|
||||
|
@ -82,21 +96,35 @@ function getVisibleMenuItems(aMenu) {
|
|||
else
|
||||
accessKeys[key] = item.id;
|
||||
}
|
||||
if (!isSpellSuggestion) {
|
||||
if (!isSpellSuggestion && !isGenerated) {
|
||||
items.push(item.id);
|
||||
}
|
||||
items.push(!item.disabled);
|
||||
if (isGenerated) {
|
||||
var p = {};
|
||||
p.type = item.getAttribute("type");
|
||||
p.icon = item.getAttribute("image");
|
||||
p.checked = item.hasAttribute("checked");
|
||||
p.disabled = item.hasAttribute("disabled");
|
||||
items.push(p);
|
||||
} else {
|
||||
items.push(!item.disabled);
|
||||
}
|
||||
} else if (item.nodeName == "menuseparator") {
|
||||
ok(true, "--- seperator id is " + item.id);
|
||||
items.push("---");
|
||||
items.push(null);
|
||||
} else if (item.nodeName == "menu") {
|
||||
if (isGenerated) {
|
||||
item.id = "generated-submenu-" + aData.generatedSubmenuId++;
|
||||
}
|
||||
ok(item.id, "child menu #" + i + " has an ID");
|
||||
ok(key, "menu has an access key");
|
||||
if (accessKeys[key])
|
||||
ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
|
||||
else
|
||||
accessKeys[key] = item.id;
|
||||
if (!isGenerated) {
|
||||
ok(key, "menu has an access key");
|
||||
if (accessKeys[key])
|
||||
ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
|
||||
else
|
||||
accessKeys[key] = item.id;
|
||||
}
|
||||
items.push(item.id);
|
||||
items.push(!item.disabled);
|
||||
// Add a dummy item to that the indexes in checkMenu are the same
|
||||
|
@ -113,7 +141,8 @@ function getVisibleMenuItems(aMenu) {
|
|||
|
||||
function checkContextMenu(expectedItems) {
|
||||
is(contextMenu.state, "open", "checking if popup is open");
|
||||
checkMenu(contextMenu, expectedItems);
|
||||
var data = { generatedSubmenuId: 1 };
|
||||
checkMenu(contextMenu, expectedItems, data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -129,8 +158,8 @@ function checkContextMenu(expectedItems) {
|
|||
* "lol", false] // item disabled
|
||||
*
|
||||
*/
|
||||
function checkMenu(menu, expectedItems) {
|
||||
var actualItems = getVisibleMenuItems(menu);
|
||||
function checkMenu(menu, expectedItems, data) {
|
||||
var actualItems = getVisibleMenuItems(menu, data);
|
||||
//ok(false, "Items are: " + actualItems);
|
||||
for (var i = 0; i < expectedItems.length; i+=2) {
|
||||
var actualItem = actualItems[i];
|
||||
|
@ -142,11 +171,40 @@ function checkMenu(menu, expectedItems) {
|
|||
var menuID = expectedItems[i - 2]; // The last item was the menu ID.
|
||||
var submenu = menu.getElementsByAttribute("id", menuID)[0];
|
||||
ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
|
||||
checkMenu(submenu.menupopup, expectedItem);
|
||||
checkMenu(submenu.menupopup, expectedItem, data);
|
||||
} else {
|
||||
is(actualItem, expectedItem,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") name");
|
||||
if (expectedEnabled != null)
|
||||
|
||||
if (typeof expectedEnabled == "object" && expectedEnabled != null ||
|
||||
typeof actualEnabled == "object" && actualEnabled != null) {
|
||||
|
||||
ok(!(actualEnabled == null), "actualEnabled is not null");
|
||||
ok(!(expectedEnabled == null), "expectedEnabled is not null");
|
||||
is(typeof actualEnabled, typeof expectedEnabled, "checking types");
|
||||
|
||||
if (typeof actualEnabled != typeof expectedEnabled ||
|
||||
actualEnabled == null || expectedEnabled == null)
|
||||
continue;
|
||||
|
||||
is(actualEnabled.type, expectedEnabled.type,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") type attr value");
|
||||
var icon = actualEnabled.icon;
|
||||
if (icon) {
|
||||
var tmp = "";
|
||||
var j = icon.length - 1;
|
||||
while (j && icon[j] != "/") {
|
||||
tmp = icon[j--] + tmp;
|
||||
}
|
||||
icon = tmp;
|
||||
}
|
||||
is(icon, expectedEnabled.icon,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") icon attr value");
|
||||
is(actualEnabled.checked, expectedEnabled.checked,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") has checked attr");
|
||||
is(actualEnabled.disabled, expectedEnabled.disabled,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") has disabled attr");
|
||||
} else if (expectedEnabled != null)
|
||||
is(actualEnabled, expectedEnabled,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") enabled state");
|
||||
}
|
||||
|
@ -408,9 +466,70 @@ function runTest(testNum) {
|
|||
openContextMenuFor(link); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 15:
|
||||
executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
|
||||
closeContextMenu();
|
||||
openContextMenuFor(pagemenu); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// Context menu for element with assigned content context menu
|
||||
checkContextMenu(["+Plain item", {type: "", icon: "", checked: false, disabled: false},
|
||||
"+Disabled item", {type: "", icon: "", checked: false, disabled: true},
|
||||
"---", null,
|
||||
"+Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
|
||||
"---", null,
|
||||
"+Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
|
||||
"+Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
|
||||
"+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
|
||||
"---", null,
|
||||
"+Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
|
||||
"+Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
|
||||
"---", null,
|
||||
"generated-submenu-1", true,
|
||||
["+Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
|
||||
"+Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
|
||||
"+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
|
||||
"---", null,
|
||||
"+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
|
||||
"---", null,
|
||||
"context-back", false,
|
||||
"context-forward", false,
|
||||
"context-reload", true,
|
||||
"context-stop", false,
|
||||
"---", null,
|
||||
"context-bookmarkpage", true,
|
||||
"context-savepage", true,
|
||||
"context-sendpage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true]);
|
||||
|
||||
invokeItemAction("0");
|
||||
closeContextMenu();
|
||||
openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 17:
|
||||
// Context menu for element with assigned content context menu
|
||||
// The shift key should bypass content context menu processing
|
||||
checkContextMenu(["context-back", false,
|
||||
"context-forward", false,
|
||||
"context-reload", true,
|
||||
"context-stop", false,
|
||||
"---", null,
|
||||
"context-bookmarkpage", true,
|
||||
"context-savepage", true,
|
||||
"context-sendpage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true]);
|
||||
|
||||
subwindow.close();
|
||||
SimpleTest.finish();
|
||||
|
@ -437,7 +556,7 @@ function runTest(testNum) {
|
|||
var testNum = 1;
|
||||
var subwindow, chromeWin, contextMenu;
|
||||
var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
|
||||
iframe, textarea, contenteditable, inputspell;
|
||||
iframe, textarea, contenteditable, inputspell, pagemenu;
|
||||
|
||||
function startTest() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
|
@ -470,6 +589,7 @@ function startTest() {
|
|||
textarea = subwindow.document.getElementById("test-textarea");
|
||||
contenteditable = subwindow.document.getElementById("test-contenteditable");
|
||||
inputspell = subwindow.document.getElementById("test-input-spellcheck");
|
||||
pagemenu = subwindow.document.getElementById("test-pagemenu");
|
||||
|
||||
contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
|
||||
runTest(1);
|
||||
|
|
|
@ -80,10 +80,10 @@
|
|||
|
||||
<popupset id="mainPopupSet">
|
||||
<tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
|
||||
<menupopup id="contentAreaContextMenu"
|
||||
<menupopup id="contentAreaContextMenu" pagemenu="start"
|
||||
onpopupshowing="if (event.target != this)
|
||||
return true;
|
||||
gContextMenu = new nsContextMenu(this, getPanelBrowser());
|
||||
gContextMenu = new nsContextMenu(this, getPanelBrowser(), event.shiftKey);
|
||||
if (gContextMenu.shouldDisplay)
|
||||
document.popupNode = this.triggerNode;
|
||||
return gContextMenu.shouldDisplay;"
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#define FILE_NAME_CERT8DB NS_LITERAL_STRING("cert8.db")
|
||||
#define FILE_NAME_KEY3DB NS_LITERAL_STRING("key3.db")
|
||||
#define FILE_NAME_SECMODDB NS_LITERAL_STRING("secmod.db")
|
||||
#define FILE_NAME_HISTORY NS_LITERAL_STRING("history.dat")
|
||||
#define FILE_NAME_MIMETYPES NS_LITERAL_STRING("mimeTypes.rdf")
|
||||
#define FILE_NAME_DOWNLOADS NS_LITERAL_STRING("downloads.rdf")
|
||||
#define FILE_NAME_PREFS NS_LITERAL_STRING("prefs.js")
|
||||
|
@ -100,7 +99,6 @@ nsSeamonkeyProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup
|
|||
|
||||
COPY_DATA(CopyPreferences, aReplace, nsIBrowserProfileMigrator::SETTINGS);
|
||||
COPY_DATA(CopyCookies, aReplace, nsIBrowserProfileMigrator::COOKIES);
|
||||
COPY_DATA(CopyHistory, aReplace, nsIBrowserProfileMigrator::HISTORY);
|
||||
COPY_DATA(CopyPasswords, aReplace, nsIBrowserProfileMigrator::PASSWORDS);
|
||||
COPY_DATA(CopyOtherData, aReplace, nsIBrowserProfileMigrator::OTHERDATA);
|
||||
|
||||
|
@ -151,9 +149,6 @@ nsSeamonkeyProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
|||
{ ToNewUnicode(FILE_NAME_COOKIES),
|
||||
nsIBrowserProfileMigrator::COOKIES,
|
||||
PR_FALSE },
|
||||
{ ToNewUnicode(FILE_NAME_HISTORY),
|
||||
nsIBrowserProfileMigrator::HISTORY,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_BOOKMARKS),
|
||||
nsIBrowserProfileMigrator::BOOKMARKS,
|
||||
PR_FALSE },
|
||||
|
@ -643,12 +638,6 @@ nsSeamonkeyProfileMigrator::CopyCookies(PRBool aReplace)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyHistory(PRBool aReplace)
|
||||
{
|
||||
return aReplace ? CopyFile(FILE_NAME_HISTORY, FILE_NAME_HISTORY) : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyPasswords(PRBool aReplace)
|
||||
{
|
||||
|
|
|
@ -91,7 +91,6 @@ protected:
|
|||
nsresult CopyUserContentSheet();
|
||||
|
||||
nsresult CopyCookies(PRBool aReplace);
|
||||
nsresult CopyHistory(PRBool aReplace);
|
||||
nsresult CopyPasswords(PRBool aReplace);
|
||||
nsresult LocateSignonsFile(char** aResult);
|
||||
nsresult CopyBookmarks(PRBool aReplace);
|
||||
|
|
|
@ -47,7 +47,6 @@ const kEnter = "enter";
|
|||
const kExit = "exit";
|
||||
|
||||
const NS_APP_USER_PROFILE_50_DIR = "ProfD";
|
||||
const NS_APP_HISTORY_50_FILE = "UHist";
|
||||
|
||||
function LOG(aMsg) {
|
||||
aMsg = ("*** PRIVATEBROWSING TESTS: " + aMsg);
|
||||
|
@ -65,26 +64,6 @@ function uri(spec) {
|
|||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
var profileDir = do_get_profile();
|
||||
|
||||
var provider = {
|
||||
getFile: function(prop, persistent) {
|
||||
persistent.value = true;
|
||||
if (prop == NS_APP_HISTORY_50_FILE) {
|
||||
var histFile = profileDir.clone();
|
||||
histFile.append("history.dat");
|
||||
return histFile;
|
||||
}
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
|
||||
iid.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
|
||||
|
||||
// Do not attempt to restore any session since we don't have any windows
|
||||
Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch).
|
||||
|
|
|
@ -1872,9 +1872,7 @@ SessionStoreService.prototype = {
|
|||
catch (ex) { debug(ex); }
|
||||
}
|
||||
|
||||
if (aEntry.docIdentifier) {
|
||||
entry.docIdentifier = aEntry.docIdentifier;
|
||||
}
|
||||
entry.docIdentifier = aEntry.BFCacheEntry.ID;
|
||||
|
||||
if (aEntry.stateData != null) {
|
||||
entry.structuredCloneState = aEntry.stateData.getDataAsBase64();
|
||||
|
@ -2982,7 +2980,6 @@ SessionStoreService.prototype = {
|
|||
browser.__SS_restore_data = tabData.entries[activeIndex] || {};
|
||||
browser.__SS_restore_pageStyle = tabData.pageStyle || "";
|
||||
browser.__SS_restore_tab = aTab;
|
||||
browser.__SS_restore_docIdentifier = curSHEntry.docIdentifier;
|
||||
|
||||
didStartLoad = true;
|
||||
try {
|
||||
|
@ -3135,24 +3132,16 @@ SessionStoreService.prototype = {
|
|||
}
|
||||
|
||||
if (aEntry.docIdentifier) {
|
||||
// Get a new document identifier for this entry to ensure that history
|
||||
// entries after a session restore are considered to have different
|
||||
// documents from the history entries before the session restore.
|
||||
// Document identifiers are 64-bit ints, so JS will loose precision and
|
||||
// start assigning all entries the same doc identifier if these ever get
|
||||
// large enough.
|
||||
//
|
||||
// It's a potential security issue if document identifiers aren't
|
||||
// globally unique, but shEntry.setUniqueDocIdentifier() below guarantees
|
||||
// that we won't re-use a doc identifier within a given instance of the
|
||||
// application.
|
||||
let ident = aDocIdentMap[aEntry.docIdentifier];
|
||||
if (!ident) {
|
||||
shEntry.setUniqueDocIdentifier();
|
||||
aDocIdentMap[aEntry.docIdentifier] = shEntry.docIdentifier;
|
||||
// If we have a serialized document identifier, try to find an SHEntry
|
||||
// which matches that doc identifier and adopt that SHEntry's
|
||||
// BFCacheEntry. If we don't find a match, insert shEntry as the match
|
||||
// for the document identifier.
|
||||
let matchingEntry = aDocIdentMap[aEntry.docIdentifier];
|
||||
if (!matchingEntry) {
|
||||
aDocIdentMap[aEntry.docIdentifier] = shEntry;
|
||||
}
|
||||
else {
|
||||
shEntry.docIdentifier = ident;
|
||||
shEntry.adoptBFCacheEntry(matchingEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3288,19 +3277,12 @@ SessionStoreService.prototype = {
|
|||
aBrowser.markupDocumentViewer.authorStyleDisabled = selectedPageStyle == "_nostyle";
|
||||
}
|
||||
|
||||
if (aBrowser.__SS_restore_docIdentifier) {
|
||||
let sh = aBrowser.webNavigation.sessionHistory;
|
||||
sh.getEntryAtIndex(sh.index, false).QueryInterface(Ci.nsISHEntry).
|
||||
docIdentifier = aBrowser.__SS_restore_docIdentifier;
|
||||
}
|
||||
|
||||
// notify the tabbrowser that this document has been completely restored
|
||||
this._sendTabRestoredNotification(aBrowser.__SS_restore_tab);
|
||||
|
||||
delete aBrowser.__SS_restore_data;
|
||||
delete aBrowser.__SS_restore_pageStyle;
|
||||
delete aBrowser.__SS_restore_tab;
|
||||
delete aBrowser.__SS_restore_docIdentifier;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,13 +116,13 @@ function test() {
|
|||
|
||||
// After these push/replaceState calls, the window should have three
|
||||
// history entries:
|
||||
// testURL (state object: null) <-- oldest
|
||||
// testURL (state object: {obj1:1})
|
||||
// page2 (state object: {obj3:/^a$/}) <-- newest
|
||||
// testURL (state object: null) <-- oldest
|
||||
// testURL (state object: {obj1:1})
|
||||
// testURL?page2 (state object: {obj3:/^a$/}) <-- newest
|
||||
let contentWindow = tab.linkedBrowser.contentWindow;
|
||||
let history = contentWindow.history;
|
||||
history.pushState({obj1:1}, "title-obj1");
|
||||
history.pushState({obj2:2}, "title-obj2", "page2");
|
||||
history.pushState({obj2:2}, "title-obj2", "?page2");
|
||||
history.replaceState({obj3:/^a$/}, "title-obj3");
|
||||
|
||||
let state = ss.getTabState(tab);
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
@BINPATH@/components/xpcom_xpti.xpt
|
||||
@BINPATH@/components/xpconnect.xpt
|
||||
@BINPATH@/components/xulapp.xpt
|
||||
@BINPATH@/components/xul.xpt
|
||||
@BINPATH@/components/xuldoc.xpt
|
||||
@BINPATH@/components/xultmpl.xpt
|
||||
@BINPATH@/components/zipwriter.xpt
|
||||
|
|
|
@ -226,6 +226,7 @@ greprefs/all.js
|
|||
greprefs/security-prefs.js
|
||||
greprefs/xpinstall.js
|
||||
install.rdf
|
||||
modules/ISO8601DateUtils.jsm
|
||||
modules/JSON.jsm
|
||||
mozilla-runtime@BIN_SUFFIX@
|
||||
old-homepage-default.properties
|
||||
|
@ -941,7 +942,6 @@ xpicleanup@BIN_SUFFIX@
|
|||
modules/Geometry.jsm
|
||||
modules/HUDService.jsm
|
||||
modules/InlineSpellChecker.jsm
|
||||
modules/ISO8601DateUtils.jsm
|
||||
modules/LightweightThemeConsumer.jsm
|
||||
modules/LightweightThemeManager.jsm
|
||||
modules/Microformats.js
|
||||
|
|
После Ширина: | Высота: | Размер: 6.3 KiB |
|
@ -88,8 +88,8 @@
|
|||
|
||||
#PersonalToolbar {
|
||||
-moz-appearance: none;
|
||||
margin-top: -1px; /* overlay the bottom border of the toolbar above us */
|
||||
padding-top: 0 !important;
|
||||
margin-top: -2px; /* overlay the bottom border of the toolbar above us */
|
||||
padding-top: 1px !important;
|
||||
background-color: -moz-mac-chrome-active;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.57);
|
||||
}
|
||||
|
@ -293,21 +293,22 @@ toolbarbutton.bookmark-item > menupopup {
|
|||
.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
|
||||
#restore-button {
|
||||
-moz-box-orient: vertical;
|
||||
padding: 0 3px;
|
||||
-moz-appearance: toolbarbutton;
|
||||
height: 22px;
|
||||
border: 1px solid @toolbarbuttonBorderColor@;
|
||||
border-radius: @toolbarbuttonCornerRadius@;
|
||||
box-shadow: 0 1px rgba(255, 255, 255, 0.2);
|
||||
background: @toolbarbuttonBackground@;
|
||||
background-origin: border-box;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.toolbarbutton-1:not([type="menu-button"]):-moz-lwtheme,
|
||||
.toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-lwtheme,
|
||||
.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-lwtheme,
|
||||
#restore-button:-moz-lwtheme {
|
||||
border-color: rgba(0, 0, 0, 0.4);
|
||||
background-image: -moz-linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.2) 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.2));
|
||||
-moz-appearance: none;
|
||||
padding: 0 3px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.4);
|
||||
border-radius: @toolbarbuttonCornerRadius@;
|
||||
background: -moz-linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.2) 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.2)) repeat-x;
|
||||
background-origin: border-box;
|
||||
box-shadow: inset 0 1px rgba(255,255,255,0.3), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
|
@ -337,6 +338,7 @@ toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]),
|
|||
toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
||||
toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
|
||||
toolbar:not([mode="icons"]) #restore-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
height: auto;
|
||||
border: none;
|
||||
|
@ -408,16 +410,6 @@ toolbar:not([mode="icons"]) .toolbarbutton-1:not([open="true"]) > .toolbarbutton
|
|||
margin: 2px 0 0;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):active:hover:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"])[open="true"]:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover:not(:-moz-lwtheme) {
|
||||
background: @toolbarbuttonPressedBackgroundColor@;
|
||||
text-shadow: @loweredShadow@;
|
||||
box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):active:hover:-moz-lwtheme,
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"])[open="true"]:-moz-lwtheme,
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover:-moz-lwtheme,
|
||||
|
@ -428,39 +420,16 @@ toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover:-moz-l
|
|||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not(:-moz-lwtheme) {
|
||||
background: #606060;
|
||||
box-shadow: inset #2A2A2A 0 3px 3.5px, @loweredShadow@;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:-moz-lwtheme {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.7), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not([disabled="true"]):active:hover:not(:-moz-lwtheme) {
|
||||
background: #4E4E4E;
|
||||
box-shadow: inset #1c1c1c 0 3px 3.5px;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not([disabled="true"]):active:hover:-moz-lwtheme {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.8), 0 1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):-moz-window-inactive:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-window-inactive:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-window-inactive:not(:-moz-lwtheme),
|
||||
toolbar[mode="icons"] #restore-button:-moz-window-inactive:not(:-moz-lwtheme) {
|
||||
border-color: @toolbarbuttonInactiveBorderColor@;
|
||||
background-image: @toolbarbuttonInactiveBackgroundImage@;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:-moz-window-inactive {
|
||||
background: #8E8E8E;
|
||||
box-shadow: inset rgba(0, 0, 0, 0.5) 0 3px 3.5px, @loweredShadow@;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] .toolbarbutton-1 > menupopup {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
@ -477,17 +446,28 @@ toolbar[mode="icons"] .toolbarbutton-1 > menupopup {
|
|||
}
|
||||
|
||||
#back-button,
|
||||
toolbar:not([mode="icons"]) #forward-button:-moz-locale-dir(rtl) {
|
||||
#forward-button:-moz-locale-dir(rtl),
|
||||
toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl):-moz-lwtheme {
|
||||
-moz-image-region: rect(0, 40px, 20px, 20px);
|
||||
}
|
||||
|
||||
#forward-button,
|
||||
toolbar:not([mode="icons"]) #back-button:-moz-locale-dir(rtl) {
|
||||
#back-button:-moz-locale-dir(rtl),
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-locale-dir(rtl),
|
||||
toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl):-moz-lwtheme {
|
||||
-moz-image-region: rect(0, 60px, 20px, 40px);
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-locale-dir(rtl),
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-locale-dir(rtl),
|
||||
toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl):-moz-lwtheme,
|
||||
toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl):-moz-lwtheme {
|
||||
-moz-transform: scaleX(-1);
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
|
||||
-moz-margin-end: -5px;
|
||||
-moz-appearance: none;
|
||||
-moz-margin-end: -7px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
-moz-image-region: rect(0, 20px, 20px, 0);
|
||||
|
@ -497,31 +477,45 @@ toolbar:not([mode="icons"]) #back-button:-moz-locale-dir(rtl) {
|
|||
border-radius: 10000px;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl),
|
||||
toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl) {
|
||||
-moz-transform: scaleX(-1);
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not(:-moz-lwtheme) {
|
||||
height: 31px;
|
||||
padding: 4px 5px 5px 3px;
|
||||
margin-bottom: -1px;
|
||||
background: url(chrome://browser/skin/keyhole-circle.png) 0 0 no-repeat;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-window-inactive:not(:-moz-lwtheme) {
|
||||
background-position: -60px 0;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):active:hover:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"]:not(:-moz-lwtheme) {
|
||||
background-position: -30px 0;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] #forward-button {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button {
|
||||
/* 1px to the right */
|
||||
padding-left: 4px;
|
||||
padding-right: 2px;
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button > .toolbarbutton-icon {
|
||||
/* shift the icon away from the back button */
|
||||
margin-left: 3px;
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-lwtheme {
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-keyhole-forward-mask);
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #forward-button {
|
||||
width: 27px;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #forward-button:-moz-lwtheme {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] #forward-button {
|
||||
toolbar[mode="icons"] #forward-button:-moz-lwtheme {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
@ -529,6 +523,9 @@ toolbar[mode="icons"] #forward-button {
|
|||
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #back-button {
|
||||
-moz-margin-end: 0;
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #back-button:-moz-lwtheme {
|
||||
padding-right: 2px;
|
||||
border-right-width: 0;
|
||||
border-top-right-radius: 0;
|
||||
|
@ -1776,34 +1773,35 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
#TabsToolbar:not(:-moz-lwtheme) {
|
||||
background-color: -moz-mac-chrome-active;
|
||||
}
|
||||
|
||||
#TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive {
|
||||
background-color: -moz-mac-chrome-inactive;
|
||||
}
|
||||
|
||||
#TabsToolbar[tabsontop="false"] {
|
||||
margin-top: -1px;
|
||||
margin-top: -2px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
/* For tabs-on-top, only fill the bottom 2px with the chrome background
|
||||
* color, so that the borders in tabbar-top-bg-*.png can mix with it.
|
||||
* In the top 24px the unified toolbar (from the ::before above) will show.
|
||||
*/
|
||||
#TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme) {
|
||||
padding-bottom: 2px;
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-active.png) ;
|
||||
background: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-active.png),
|
||||
-moz-linear-gradient(bottom, -moz-mac-chrome-active 2px, transparent 2px);
|
||||
}
|
||||
|
||||
#TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme):-moz-window-inactive {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-inactive.png);
|
||||
background: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-inactive.png),
|
||||
-moz-linear-gradient(bottom, -moz-mac-chrome-inactive 2px, transparent 2px);
|
||||
}
|
||||
|
||||
/* In tabs-on-bottom mode, fill the whole toolbar with the chrome
|
||||
* background color.
|
||||
*/
|
||||
#TabsToolbar[tabsontop="false"]:not(:-moz-lwtheme) {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-active.png);
|
||||
background: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-active.png) -moz-mac-chrome-active;
|
||||
}
|
||||
|
||||
#TabsToolbar[tabsontop="false"]:not(:-moz-lwtheme):-moz-window-inactive {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-inactive.png);
|
||||
background: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-inactive.png) -moz-mac-chrome-inactive;
|
||||
}
|
||||
|
||||
#tabbrowser-tabs {
|
||||
|
@ -1955,11 +1953,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1,
|
||||
:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
||||
:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
-moz-appearance: none;
|
||||
/* !important flags needed because of bug 561154: */
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
background: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ browser.jar:
|
|||
skin/classic/browser/section_collapsed-rtl.png
|
||||
skin/classic/browser/section_expanded.png
|
||||
skin/classic/browser/Secure-Glyph-White.png
|
||||
skin/classic/browser/keyhole-circle.png
|
||||
skin/classic/browser/Toolbar.png
|
||||
skin/classic/browser/toolbarbutton-dropmarker.png
|
||||
skin/classic/browser/urlbar-arrow.png
|
||||
|
@ -134,3 +135,8 @@ browser.jar:
|
|||
skin/classic/browser/syncCommon.css
|
||||
skin/classic/browser/syncQuota.css
|
||||
#endif
|
||||
skin/classic/browser/lion/keyhole-circle.png (keyhole-circle-lion.png)
|
||||
skin/classic/browser/lion/Toolbar.png (Toolbar-lion.png)
|
||||
|
||||
% override chrome://browser/skin/keyhole-circle.png chrome://browser/skin/lion/keyhole-circle.png os=Darwin osversion>=10.7
|
||||
% override chrome://browser/skin/Toolbar.png chrome://browser/skin/lion/Toolbar.png os=Darwin osversion>=10.7
|
||||
|
|
После Ширина: | Высота: | Размер: 2.2 KiB |
После Ширина: | Высота: | Размер: 2.2 KiB |
|
@ -80,33 +80,9 @@
|
|||
#placesToolbar > toolbarbutton {
|
||||
list-style-image: url("chrome://browser/skin/places/toolbar.png");
|
||||
margin: 4px 4px 5px;
|
||||
padding: 1px 3px;
|
||||
border: 1px solid @toolbarbuttonBorderColor@;
|
||||
border-radius: @toolbarbuttonCornerRadius@;
|
||||
box-shadow: @loweredShadow@;
|
||||
background: @toolbarbuttonBackground@;
|
||||
background-origin: border-box;
|
||||
}
|
||||
|
||||
#placesToolbar > toolbarbutton:not([disabled="true"]):active:hover,
|
||||
#placesToolbar > toolbarbutton[open="true"] {
|
||||
background: @toolbarbuttonPressedBackgroundColor@;
|
||||
text-shadow: @loweredShadow@;
|
||||
box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
|
||||
}
|
||||
|
||||
#placesToolbar > toolbarbutton:-moz-focusring {
|
||||
border-color: @toolbarbuttonFocusedBorderColorAqua@;
|
||||
box-shadow: @focusRingShadow@;
|
||||
}
|
||||
|
||||
#placesToolbar > toolbarbutton:-moz-system-metric(mac-graphite-theme):-moz-focusring {
|
||||
border-color: @toolbarbuttonFocusedBorderColorGraphite@;
|
||||
}
|
||||
|
||||
#placesToolbar > toolbarbutton:-moz-window-inactive {
|
||||
border-color: @toolbarbuttonInactiveBorderColor@;
|
||||
background-image: @toolbarbuttonInactiveBackgroundImage@;
|
||||
padding: 0;
|
||||
height: 22px;
|
||||
-moz-appearance: toolbarbutton;
|
||||
}
|
||||
|
||||
#placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon {
|
||||
|
@ -136,17 +112,12 @@
|
|||
#back-button:-moz-locale-dir(ltr),
|
||||
#forward-button:-moz-locale-dir(rtl) {
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
margin-right: 0;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
#forward-button:-moz-locale-dir(ltr),
|
||||
#back-button:-moz-locale-dir(rtl) {
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
|
До Ширина: | Высота: | Размер: 291 B После Ширина: | Высота: | Размер: 121 B |
До Ширина: | Высота: | Размер: 394 B После Ширина: | Высота: | Размер: 118 B |
|
@ -143,12 +143,9 @@ MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
|||
MOZ_FEEDS = @MOZ_FEEDS@
|
||||
MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
|
||||
MOZ_PLACES = @MOZ_PLACES@
|
||||
MOZ_STORAGE = @MOZ_STORAGE@
|
||||
MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
|
||||
MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@
|
||||
MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
|
||||
MOZ_MORK = @MOZ_MORK@
|
||||
MOZ_MORKREADER = @MOZ_MORKREADER@
|
||||
MOZ_OGG = @MOZ_OGG@
|
||||
MOZ_RAW = @MOZ_RAW@
|
||||
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
||||
|
|
98
configure.in
|
@ -3892,63 +3892,6 @@ if test "x$ac_cv_va_val_copy" = "xno"; then
|
|||
fi
|
||||
AC_MSG_RESULT($ac_cv_va_val_copy)
|
||||
|
||||
dnl Check for dll-challenged libc's.
|
||||
dnl This check is apparently only needed for Linux.
|
||||
case "$target" in
|
||||
*-linux*)
|
||||
dnl ===================================================================
|
||||
_curdir=`pwd`
|
||||
export _curdir
|
||||
rm -rf conftest* _conftest
|
||||
mkdir _conftest
|
||||
cat >> conftest.C <<\EOF
|
||||
#include <stdio.h>
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
#ifdef _dl_loaded
|
||||
void __dump_link_map(void) {
|
||||
struct link_map *map = _dl_loaded;
|
||||
while (NULL != map) {printf("0x%08x %s\n", map->l_addr, map->l_name); map = map->l_next;}
|
||||
}
|
||||
int main() {
|
||||
dlopen("./conftest1.so",RTLD_LAZY);
|
||||
dlopen("./../_conftest/conftest1.so",RTLD_LAZY);
|
||||
dlopen("CURDIR/_conftest/conftest1.so",RTLD_LAZY);
|
||||
dlopen("CURDIR/_conftest/../_conftest/conftest1.so",RTLD_LAZY);
|
||||
__dump_link_map();
|
||||
}
|
||||
#else
|
||||
/* _dl_loaded isn't defined, so this should be either a libc5 (glibc1) system, or a glibc2 system that doesn't have the multiple load bug (i.e., RH6.0).*/
|
||||
int main() { printf("./conftest1.so\n"); }
|
||||
#endif
|
||||
EOF
|
||||
|
||||
$PERL -p -i -e "s/CURDIR/\$ENV{_curdir}/g;" conftest.C
|
||||
|
||||
cat >> conftest1.C <<\EOF
|
||||
#include <stdio.h>
|
||||
void foo(void) {printf("foo in dll called\n");}
|
||||
EOF
|
||||
${CXX-g++} -fPIC -c -g conftest1.C
|
||||
${CXX-g++} -shared -Wl,-h -Wl,conftest1.so -o conftest1.so conftest1.o
|
||||
${CXX-g++} -g conftest.C -o conftest -ldl
|
||||
cp -f conftest1.so conftest _conftest
|
||||
cd _conftest
|
||||
if test `./conftest | grep conftest1.so | wc -l` -gt 1
|
||||
then
|
||||
echo
|
||||
echo "*** Your libc has a bug that can result in loading the same dynamic"
|
||||
echo "*** library multiple times. This bug is known to be fixed in glibc-2.0.7-32"
|
||||
echo "*** or later. However, if you choose not to upgrade, the only effect"
|
||||
echo "*** will be excessive memory usage at runtime."
|
||||
echo
|
||||
fi
|
||||
cd ${_curdir}
|
||||
rm -rf conftest* _conftest
|
||||
dnl ===================================================================
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl ===================================================================
|
||||
dnl ========================================================
|
||||
dnl Put your C++ language/feature checks below
|
||||
|
@ -4631,11 +4574,6 @@ if test "$SYSTEM_JPEG" = 1; then
|
|||
SYSTEM_JPEG=1,
|
||||
[SYSTEM_JPEG= JPEG_CFLAGS= JPEG_LIBS=])
|
||||
fi
|
||||
|
||||
MOZ_LIBJPEG_TURBO=
|
||||
if test -z "$SYSTEM_JPEG"; then
|
||||
MOZ_LIBJPEG_TURBO=1
|
||||
fi
|
||||
CFLAGS=$_SAVE_CFLAGS
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
LIBS=$_SAVE_LIBS
|
||||
|
@ -4821,8 +4759,6 @@ MOZ_OFFICIAL_BRANDING=
|
|||
MOZ_FEEDS=1
|
||||
MOZ_INSTALLER=1
|
||||
MOZ_JSDEBUGGER=1
|
||||
MOZ_MORK=
|
||||
MOZ_MORKREADER=
|
||||
MOZ_AUTH_EXTENSION=1
|
||||
MOZ_OGG=1
|
||||
MOZ_RAW=
|
||||
|
@ -4854,7 +4790,6 @@ MOZ_REFLOW_PERF=
|
|||
MOZ_SAFE_BROWSING=
|
||||
MOZ_HELP_VIEWER=
|
||||
MOZ_SPELLCHECK=1
|
||||
MOZ_STORAGE=1
|
||||
MOZ_SVG_DLISTS=
|
||||
MOZ_TOOLKIT_SEARCH=1
|
||||
MOZ_UI_LOCALE=en-US
|
||||
|
@ -6256,12 +6191,20 @@ AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_P
|
|||
dnl ========================================================
|
||||
dnl = libjpeg-turbo configuration
|
||||
dnl ========================================================
|
||||
MOZ_LIBJPEG_TURBO=
|
||||
if test -z "$SYSTEM_JPEG"; then
|
||||
MOZ_LIBJPEG_TURBO=1
|
||||
fi
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(libjpeg_turbo,
|
||||
[ --disable-libjpeg-turbo Disable optimized jpeg decoding routines],
|
||||
MOZ_LIBJPEG_TURBO=,
|
||||
MOZ_LIBJPEG_TURBO=1)
|
||||
|
||||
if test "$SYSTEM_JPEG" = 1 -a "$MOZ_LIBJPEG_TURBO" = 1; then
|
||||
AC_MSG_ERROR([cannot use --with-system-jpeg with --enable-libjpeg-turbo.])
|
||||
fi
|
||||
|
||||
dnl Detect if we can use yasm to compile libjpeg-turbo's optimized assembly
|
||||
dnl files.
|
||||
|
||||
|
@ -6605,18 +6548,6 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable mozStorage
|
||||
dnl ========================================================
|
||||
dnl Implicitly enabled by default if building calendar or places
|
||||
MOZ_ARG_ENABLE_BOOL(storage,
|
||||
[ --enable-storage Enable mozStorage module and related components],
|
||||
MOZ_STORAGE=1,
|
||||
MOZ_STORAGE= )
|
||||
if test -n "$MOZ_STORAGE"; then
|
||||
AC_DEFINE(MOZ_STORAGE)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Check for sqlite
|
||||
dnl ========================================================
|
||||
|
@ -8888,18 +8819,6 @@ fi
|
|||
dnl NECKO_ configuration options are not global
|
||||
_NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_"
|
||||
|
||||
dnl Only build Mork if it's required
|
||||
AC_SUBST(MOZ_MORK)
|
||||
if test "$MOZ_MORK"; then
|
||||
AC_DEFINE(MOZ_MORK)
|
||||
fi
|
||||
|
||||
dnl Build the lightweight Mork reader if required
|
||||
AC_SUBST(MOZ_MORKREADER)
|
||||
if test "$MOZ_MORKREADER"; then
|
||||
AC_DEFINE(MOZ_MORKREADER)
|
||||
fi
|
||||
|
||||
dnl Build Places if required
|
||||
if test "$MOZ_PLACES"; then
|
||||
AC_DEFINE(MOZ_PLACES)
|
||||
|
@ -8979,7 +8898,6 @@ AC_SUBST(MOZ_PROFILING)
|
|||
AC_SUBST(MOZ_QUANTIFY)
|
||||
AC_SUBST(LIBICONV)
|
||||
AC_SUBST(MOZ_PLACES)
|
||||
AC_SUBST(MOZ_STORAGE)
|
||||
AC_SUBST(MOZ_TOOLKIT_SEARCH)
|
||||
AC_SUBST(MOZ_FEEDS)
|
||||
AC_SUBST(NS_PRINTING)
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "nsIAnimationFrameListener.h"
|
||||
#include "nsEventStates.h"
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "nsIBFCacheEntry.h"
|
||||
#include "nsDOMMemoryReporter.h"
|
||||
|
||||
class nsIContent;
|
||||
|
@ -125,9 +126,9 @@ class Element;
|
|||
} // namespace mozilla
|
||||
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0xfac563fb, 0x2b6a, 0x4ac8, \
|
||||
{ 0x85, 0xf7, 0xd5, 0x14, 0x4b, 0x3e, 0xce, 0x78 } }
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x455e4d79, 0x756b, 0x4f73, \
|
||||
{ 0x95, 0xea, 0x3f, 0xf6, 0x0c, 0x6a, 0x8c, 0xa6 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -480,11 +481,15 @@ public:
|
|||
return GetBFCacheEntry() ? nsnull : mPresShell;
|
||||
}
|
||||
|
||||
void SetBFCacheEntry(nsISHEntry* aSHEntry) {
|
||||
mSHEntry = aSHEntry;
|
||||
void SetBFCacheEntry(nsIBFCacheEntry* aEntry)
|
||||
{
|
||||
mBFCacheEntry = aEntry;
|
||||
}
|
||||
|
||||
nsISHEntry* GetBFCacheEntry() const { return mSHEntry; }
|
||||
nsIBFCacheEntry* GetBFCacheEntry() const
|
||||
{
|
||||
return mBFCacheEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parent document of this document. Will return null
|
||||
|
@ -1326,6 +1331,10 @@ public:
|
|||
|
||||
PRUint32 EventHandlingSuppressed() const { return mEventsSuppressed; }
|
||||
|
||||
bool IsEventHandlingEnabled() {
|
||||
return !EventHandlingSuppressed() && mScriptGlobalObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the number of external scripts being evaluated.
|
||||
*/
|
||||
|
@ -1738,9 +1747,9 @@ protected:
|
|||
|
||||
AnimationListenerList mAnimationFrameListeners;
|
||||
|
||||
// The session history entry in which we're currently bf-cached. Non-null
|
||||
// if and only if we're currently in the bfcache.
|
||||
nsISHEntry* mSHEntry;
|
||||
// This object allows us to evict ourself from the back/forward cache. The
|
||||
// pointer is non-null iff we're currently in the bfcache.
|
||||
nsIBFCacheEntry *mBFCacheEntry;
|
||||
|
||||
// Our base target.
|
||||
nsString mBaseTarget;
|
||||
|
|
|
@ -51,7 +51,7 @@ interface nsIDroppedLinkHandler : nsISupports
|
|||
* includes any parent, sibling and child frames in the same content tree.
|
||||
* If true, the source is not checked.
|
||||
*/
|
||||
boolean canDropLink(in nsIDOMDragEvent aEvent, in PRBool aAllowSameDocument);
|
||||
boolean canDropLink(in nsIDOMDragEvent aEvent, in boolean aAllowSameDocument);
|
||||
|
||||
/**
|
||||
* Given a drop event aEvent, determines the link being dragged and returns
|
||||
|
|
|
@ -63,14 +63,14 @@ interface nsISelection2 : nsISelection
|
|||
void GetRangesForInterval(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in PRBool allowAdjacent,
|
||||
in boolean allowAdjacent,
|
||||
out PRUint32 resultCount,
|
||||
[retval, array, size_is(resultCount)] out nsIDOMRange results);
|
||||
|
||||
[noscript] void GetRangesForIntervalCOMArray(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in PRBool allowAdjacent,
|
||||
in boolean allowAdjacent,
|
||||
in RangeArray results);
|
||||
|
||||
/**
|
||||
|
|
|
@ -492,172 +492,14 @@ nsContentUtils::InitializeEventTable() {
|
|||
NS_ASSERTION(!sStringEventTable, "EventTable already initialized!");
|
||||
|
||||
static const EventNameMapping eventArray[] = {
|
||||
{ nsGkAtoms::onmousedown, NS_MOUSE_BUTTON_DOWN, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onmouseup, NS_MOUSE_BUTTON_UP, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onclick, NS_MOUSE_CLICK, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::ondblclick, NS_MOUSE_DOUBLECLICK, EventNameType_HTMLXUL, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onmouseover, NS_MOUSE_ENTER_SYNTH, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onmouseout, NS_MOUSE_EXIT_SYNTH, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onMozMouseHittest, NS_MOUSE_MOZHITTEST, EventNameType_None, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::onmousemove, NS_MOUSE_MOVE, EventNameType_All, NS_MOUSE_EVENT },
|
||||
{ nsGkAtoms::oncontextmenu, NS_CONTEXTMENU, EventNameType_HTMLXUL, NS_MOUSE_EVENT },
|
||||
|
||||
{ nsGkAtoms::onkeydown, NS_KEY_DOWN, EventNameType_HTMLXUL, NS_KEY_EVENT },
|
||||
{ nsGkAtoms::onkeyup, NS_KEY_UP, EventNameType_HTMLXUL, NS_KEY_EVENT },
|
||||
{ nsGkAtoms::onkeypress, NS_KEY_PRESS, EventNameType_HTMLXUL, NS_KEY_EVENT },
|
||||
|
||||
{ nsGkAtoms::onfocus, NS_FOCUS_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT },
|
||||
{ nsGkAtoms::onblur, NS_BLUR_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT },
|
||||
|
||||
{ nsGkAtoms::onoffline, NS_OFFLINE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::ononline, NS_ONLINE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onsubmit, NS_FORM_SUBMIT, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onreset, NS_FORM_RESET, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onchange, NS_FORM_CHANGE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onselect, NS_FORM_SELECTED, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::oninvalid, NS_FORM_INVALID, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onload, NS_LOAD, EventNameType_All, NS_EVENT },
|
||||
{ nsGkAtoms::onpopstate, NS_POPSTATE, EventNameType_HTMLXUL, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onunload, NS_PAGE_UNLOAD,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
||||
{ nsGkAtoms::onhashchange, NS_HASHCHANGE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onreadystatechange, NS_READYSTATECHANGE, EventNameType_HTMLXUL },
|
||||
{ nsGkAtoms::onbeforeunload, NS_BEFORE_PAGE_UNLOAD, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onabort, NS_IMAGE_ABORT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
||||
{ nsGkAtoms::onerror, NS_LOAD_ERROR,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
||||
{ nsGkAtoms::onbeforescriptexecute, NS_BEFORE_SCRIPT_EXECUTE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onafterscriptexecute, NS_AFTER_SCRIPT_EXECUTE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
|
||||
{ nsGkAtoms::onDOMAttrModified, NS_MUTATION_ATTRMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMCharacterDataModified, NS_MUTATION_CHARACTERDATAMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMNodeInserted, NS_MUTATION_NODEINSERTED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMNodeRemoved, NS_MUTATION_NODEREMOVED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMNodeInsertedIntoDocument, NS_MUTATION_NODEINSERTEDINTODOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMNodeRemovedFromDocument, NS_MUTATION_NODEREMOVEDFROMDOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
{ nsGkAtoms::onDOMSubtreeModified, NS_MUTATION_SUBTREEMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
|
||||
|
||||
{ nsGkAtoms::onDOMActivate, NS_UI_ACTIVATE, EventNameType_HTMLXUL, NS_UI_EVENT },
|
||||
{ nsGkAtoms::onDOMFocusIn, NS_UI_FOCUSIN, EventNameType_HTMLXUL, NS_UI_EVENT },
|
||||
{ nsGkAtoms::onDOMFocusOut, NS_UI_FOCUSOUT, EventNameType_HTMLXUL, NS_UI_EVENT },
|
||||
{ nsGkAtoms::oninput, NS_FORM_INPUT, EventNameType_HTMLXUL, NS_UI_EVENT },
|
||||
|
||||
{ nsGkAtoms::onDOMMouseScroll, NS_MOUSE_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
|
||||
{ nsGkAtoms::onMozMousePixelScroll, NS_MOUSE_PIXEL_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
|
||||
|
||||
{ nsGkAtoms::onpageshow, NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT },
|
||||
{ nsGkAtoms::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
|
||||
{ nsGkAtoms::onMozBeforeResize, NS_BEFORERESIZE_EVENT, EventNameType_None, NS_EVENT },
|
||||
{ nsGkAtoms::onresize, NS_RESIZE_EVENT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
||||
{ nsGkAtoms::onscroll, NS_SCROLL_EVENT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT_NULL },
|
||||
{ nsGkAtoms::oncopy, NS_COPY, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::oncut, NS_CUT, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onpaste, NS_PASTE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onopen, NS_OPEN, EventNameType_None, NS_EVENT },
|
||||
{ nsGkAtoms::onmessage, NS_MESSAGE, EventNameType_None, NS_EVENT },
|
||||
// XUL specific events
|
||||
{ nsGkAtoms::ontext, NS_TEXT_TEXT, EventNameType_XUL, NS_EVENT_NULL },
|
||||
|
||||
{ nsGkAtoms::oncompositionstart, NS_COMPOSITION_START, EventNameType_XUL, NS_COMPOSITION_EVENT },
|
||||
{ nsGkAtoms::oncompositionend, NS_COMPOSITION_END, EventNameType_XUL, NS_COMPOSITION_EVENT },
|
||||
|
||||
{ nsGkAtoms::oncommand, NS_XUL_COMMAND, EventNameType_XUL, NS_INPUT_EVENT },
|
||||
|
||||
{ nsGkAtoms::onclose, NS_XUL_CLOSE, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onpopupshowing, NS_XUL_POPUP_SHOWING, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onpopupshown, NS_XUL_POPUP_SHOWN, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onpopuphiding, NS_XUL_POPUP_HIDING, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onpopuphidden, NS_XUL_POPUP_HIDDEN, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onbroadcast, NS_XUL_BROADCAST, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::oncommandupdate, NS_XUL_COMMAND_UPDATE, EventNameType_XUL, NS_EVENT_NULL},
|
||||
|
||||
{ nsGkAtoms::ondragenter, NS_DRAGDROP_ENTER, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragover, NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragexit, NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragdrop, NS_DRAGDROP_DRAGDROP, EventNameType_XUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondraggesture, NS_DRAGDROP_GESTURE, EventNameType_XUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondrag, NS_DRAGDROP_DRAG, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragend, NS_DRAGDROP_END, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragstart, NS_DRAGDROP_START, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondragleave, NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
{ nsGkAtoms::ondrop, NS_DRAGDROP_DROP, EventNameType_HTMLXUL, NS_DRAG_EVENT },
|
||||
|
||||
{ nsGkAtoms::onoverflow, NS_SCROLLPORT_OVERFLOW, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onunderflow, NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL, NS_EVENT_NULL},
|
||||
{ nsGkAtoms::onSVGLoad, NS_SVG_LOAD, EventNameType_None, NS_SVG_EVENT },
|
||||
{ nsGkAtoms::onSVGUnload, NS_SVG_UNLOAD, EventNameType_None, NS_SVG_EVENT },
|
||||
{ nsGkAtoms::onSVGAbort, NS_SVG_ABORT, EventNameType_None, NS_SVG_EVENT },
|
||||
{ nsGkAtoms::onSVGError, NS_SVG_ERROR, EventNameType_None, NS_SVG_EVENT },
|
||||
{ nsGkAtoms::onSVGResize, NS_SVG_RESIZE, EventNameType_None, NS_SVG_EVENT },
|
||||
{ nsGkAtoms::onSVGScroll, NS_SVG_SCROLL, EventNameType_None, NS_SVG_EVENT },
|
||||
|
||||
{ nsGkAtoms::onSVGZoom, NS_SVG_ZOOM, EventNameType_None, NS_SVGZOOM_EVENT },
|
||||
|
||||
// This is a bit hackish, but SVG's event names are weird.
|
||||
{ nsGkAtoms::onzoom, NS_SVG_ZOOM, EventNameType_SVGSVG, NS_EVENT_NULL },
|
||||
#ifdef MOZ_SMIL
|
||||
{ nsGkAtoms::onbegin, NS_SMIL_BEGIN, EventNameType_SMIL, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onbeginEvent, NS_SMIL_BEGIN, EventNameType_None, NS_SMIL_TIME_EVENT },
|
||||
{ nsGkAtoms::onend, NS_SMIL_END, EventNameType_SMIL, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onendEvent, NS_SMIL_END, EventNameType_None, NS_SMIL_TIME_EVENT },
|
||||
{ nsGkAtoms::onrepeat, NS_SMIL_REPEAT, EventNameType_SMIL, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onrepeatEvent, NS_SMIL_REPEAT, EventNameType_None, NS_SMIL_TIME_EVENT },
|
||||
#endif // MOZ_SMIL
|
||||
#ifdef MOZ_MEDIA
|
||||
{ nsGkAtoms::onloadstart, NS_LOADSTART, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onprogress, NS_PROGRESS, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onsuspend, NS_SUSPEND, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onemptied, NS_EMPTIED, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onstalled, NS_STALLED, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onplay, NS_PLAY, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onpause, NS_PAUSE, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onloadedmetadata, NS_LOADEDMETADATA, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onloadeddata, NS_LOADEDDATA, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onwaiting, NS_WAITING, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onplaying, NS_PLAYING, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::oncanplay, NS_CANPLAY, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::oncanplaythrough, NS_CANPLAYTHROUGH, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onseeking, NS_SEEKING, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onseeked, NS_SEEKED, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::ontimeupdate, NS_TIMEUPDATE, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onended, NS_ENDED, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onratechange, NS_RATECHANGE, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::ondurationchange, NS_DURATIONCHANGE, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onvolumechange, NS_VOLUMECHANGE, EventNameType_HTML, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onMozAudioAvailable, NS_MOZAUDIOAVAILABLE, EventNameType_None, NS_EVENT_NULL },
|
||||
#endif // MOZ_MEDIA
|
||||
{ nsGkAtoms::onMozAfterPaint, NS_AFTERPAINT, EventNameType_None, NS_EVENT },
|
||||
{ nsGkAtoms::onMozBeforePaint, NS_BEFOREPAINT, EventNameType_None, NS_EVENT_NULL },
|
||||
|
||||
{ nsGkAtoms::onMozScrolledAreaChanged, NS_SCROLLEDAREACHANGED, EventNameType_None, NS_SCROLLAREA_EVENT },
|
||||
|
||||
// Simple gesture events
|
||||
{ nsGkAtoms::onMozSwipeGesture, NS_SIMPLE_GESTURE_SWIPE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozMagnifyGestureStart, NS_SIMPLE_GESTURE_MAGNIFY_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozMagnifyGestureUpdate, NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozMagnifyGesture, NS_SIMPLE_GESTURE_MAGNIFY, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozRotateGestureStart, NS_SIMPLE_GESTURE_ROTATE_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozRotateGestureUpdate, NS_SIMPLE_GESTURE_ROTATE_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozRotateGesture, NS_SIMPLE_GESTURE_ROTATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozTapGesture, NS_SIMPLE_GESTURE_TAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
{ nsGkAtoms::onMozPressTapGesture, NS_SIMPLE_GESTURE_PRESSTAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
|
||||
|
||||
{ nsGkAtoms::onMozTouchDown, NS_MOZTOUCH_DOWN, EventNameType_None, NS_MOZTOUCH_EVENT },
|
||||
{ nsGkAtoms::onMozTouchMove, NS_MOZTOUCH_MOVE, EventNameType_None, NS_MOZTOUCH_EVENT },
|
||||
{ nsGkAtoms::onMozTouchUp, NS_MOZTOUCH_UP, EventNameType_None, NS_MOZTOUCH_EVENT },
|
||||
|
||||
{ nsGkAtoms::ondevicemotion, NS_DEVICE_MOTION, EventNameType_None, NS_EVENT },
|
||||
{ nsGkAtoms::ondeviceorientation, NS_DEVICE_ORIENTATION, EventNameType_None, NS_EVENT },
|
||||
|
||||
{ nsGkAtoms::ontransitionend, NS_TRANSITION_END, EventNameType_None, NS_TRANSITION_EVENT },
|
||||
{ nsGkAtoms::onanimationstart, NS_ANIMATION_START, EventNameType_None, NS_ANIMATION_EVENT },
|
||||
{ nsGkAtoms::onanimationend, NS_ANIMATION_END, EventNameType_None, NS_ANIMATION_EVENT },
|
||||
{ nsGkAtoms::onanimationiteration, NS_ANIMATION_ITERATION, EventNameType_None, NS_ANIMATION_EVENT },
|
||||
{ nsGkAtoms::onbeforeprint, NS_BEFOREPRINT, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onafterprint, NS_AFTERPRINT, EventNameType_HTMLXUL, NS_EVENT }
|
||||
#define EVENT(name_, _id, _type, _struct) \
|
||||
{ nsGkAtoms::on##name_, _id, _type, _struct },
|
||||
#define WINDOW_ONLY_EVENT EVENT
|
||||
#define NON_IDL_EVENT EVENT
|
||||
#include "nsEventNameList.h"
|
||||
#undef WINDOW_ONLY_EVENT
|
||||
#undef EVENT
|
||||
nsnull
|
||||
};
|
||||
|
||||
sAtomEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;
|
||||
|
@ -676,7 +518,8 @@ nsContentUtils::InitializeEventTable() {
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray); ++i) {
|
||||
// Subtract one from the length because of the trailing null
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray) - 1; ++i) {
|
||||
if (!sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]) ||
|
||||
!sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
|
||||
eventArray[i])) {
|
||||
|
@ -698,14 +541,16 @@ nsContentUtils::InitializeTouchEventTable()
|
|||
if (!sEventTableInitialized && sAtomEventTable && sStringEventTable) {
|
||||
sEventTableInitialized = PR_TRUE;
|
||||
static const EventNameMapping touchEventArray[] = {
|
||||
{ nsGkAtoms::ontouchstart, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT },
|
||||
{ nsGkAtoms::ontouchend, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT },
|
||||
{ nsGkAtoms::ontouchmove, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT },
|
||||
{ nsGkAtoms::ontouchenter, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT },
|
||||
{ nsGkAtoms::ontouchleave, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT },
|
||||
{ nsGkAtoms::ontouchcancel, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }
|
||||
#define EVENT(name_, _id, _type, _struct)
|
||||
#define TOUCH_EVENT(name_, _id, _type, _struct) \
|
||||
{ nsGkAtoms::on##name_, _id, _type, _struct },
|
||||
#include "nsEventNameList.h"
|
||||
#undef TOUCH_EVENT
|
||||
#undef EVENT
|
||||
nsnull
|
||||
};
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(touchEventArray); ++i) {
|
||||
// Subtract one from the length because of the trailing null
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(touchEventArray) - 1; ++i) {
|
||||
if (!sAtomEventTable->Put(touchEventArray[i].mAtom, touchEventArray[i]) ||
|
||||
!sStringEventTable->Put(Substring(nsDependentAtomString(touchEventArray[i].mAtom), 2),
|
||||
touchEventArray[i])) {
|
||||
|
|
|
@ -3196,9 +3196,7 @@ nsDocument::doCreateShell(nsPresContext* aContext,
|
|||
|
||||
mExternalResourceMap.ShowViewers();
|
||||
|
||||
if (mScriptGlobalObject) {
|
||||
RescheduleAnimationFrameNotifications();
|
||||
}
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
|
||||
shell.swap(*aInstancePtrResult);
|
||||
|
||||
|
@ -3206,8 +3204,13 @@ nsDocument::doCreateShell(nsPresContext* aContext,
|
|||
}
|
||||
|
||||
void
|
||||
nsDocument::RescheduleAnimationFrameNotifications()
|
||||
nsDocument::MaybeRescheduleAnimationFrameNotifications()
|
||||
{
|
||||
if (!mPresShell || !IsEventHandlingEnabled()) {
|
||||
// bail out for now, until one of those conditions changes
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
|
||||
if (mHavePendingPaint) {
|
||||
rd->ScheduleBeforePaintEvent(this);
|
||||
|
@ -3228,7 +3231,7 @@ void
|
|||
nsDocument::DeleteShell()
|
||||
{
|
||||
mExternalResourceMap.HideViewers();
|
||||
if (mScriptGlobalObject) {
|
||||
if (IsEventHandlingEnabled()) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
mPresShell = nsnull;
|
||||
|
@ -3776,7 +3779,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
// our layout history state now.
|
||||
mLayoutHistoryState = GetLayoutHistoryState();
|
||||
|
||||
if (mPresShell) {
|
||||
if (mPresShell && !EventHandlingSuppressed()) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
|
@ -3837,9 +3840,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
}
|
||||
}
|
||||
|
||||
if (mPresShell) {
|
||||
RescheduleAnimationFrameNotifications();
|
||||
}
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
// Remember the pointer to our window (or lack there of), to avoid
|
||||
|
@ -7648,6 +7649,10 @@ SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
|
|||
void
|
||||
nsDocument::SuppressEventHandling(PRUint32 aIncrease)
|
||||
{
|
||||
if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
|
||||
mScriptGlobalObject) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
mEventsSuppressed += aIncrease;
|
||||
EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
|
||||
}
|
||||
|
@ -7807,13 +7812,8 @@ GetAndUnsuppressSubDocuments(nsIDocument* aDocument, void* aData)
|
|||
void
|
||||
nsDocument::UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents)
|
||||
{
|
||||
if (mEventsSuppressed > 0) {
|
||||
--mEventsSuppressed;
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<nsIDocument> > documents;
|
||||
documents.AppendElement(this);
|
||||
EnumerateSubDocuments(GetAndUnsuppressSubDocuments, &documents);
|
||||
GetAndUnsuppressSubDocuments(this, &documents);
|
||||
|
||||
if (aFireEvents) {
|
||||
NS_DispatchToCurrentThread(new nsDelayedEventDispatcher(documents));
|
||||
|
@ -8042,7 +8042,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
|
|||
if (aListener) {
|
||||
PRBool alreadyRegistered = !mAnimationFrameListeners.IsEmpty();
|
||||
if (mAnimationFrameListeners.AppendElement(aListener) &&
|
||||
!alreadyRegistered && mPresShell) {
|
||||
!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
|
||||
mPresShell->GetPresContext()->RefreshDriver()->
|
||||
ScheduleAnimationFrameListeners(this);
|
||||
}
|
||||
|
@ -8056,6 +8056,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
|
|||
// event will fire, or we'll quietly go away at some point.
|
||||
mHavePendingPaint =
|
||||
!mPresShell ||
|
||||
!IsEventHandlingEnabled() ||
|
||||
mPresShell->GetPresContext()->RefreshDriver()->
|
||||
ScheduleBeforePaintEvent(this);
|
||||
}
|
||||
|
|
|
@ -865,7 +865,10 @@ public:
|
|||
|
||||
virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents);
|
||||
|
||||
void DecreaseEventSuppression() { --mEventsSuppressed; }
|
||||
void DecreaseEventSuppression() {
|
||||
--mEventsSuppressed;
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
|
||||
nsIDocument)
|
||||
|
@ -1149,8 +1152,9 @@ private:
|
|||
|
||||
// Revoke any pending notifications due to mozRequestAnimationFrame calls
|
||||
void RevokeAnimationFrameNotifications();
|
||||
// Reschedule any notifications we need to handle mozRequestAnimationFrame
|
||||
void RescheduleAnimationFrameNotifications();
|
||||
// Reschedule any notifications we need to handle
|
||||
// mozRequestAnimationFrame, if it's OK to do so.
|
||||
void MaybeRescheduleAnimationFrameNotifications();
|
||||
|
||||
// These are not implemented and not supported.
|
||||
nsDocument(const nsDocument& aOther);
|
||||
|
|
|
@ -249,7 +249,7 @@ nsFrameMessageManager::SendSyncMessage()
|
|||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
if (!retval[i].Length())
|
||||
if (retval[i].IsEmpty())
|
||||
continue;
|
||||
|
||||
jsval ret = JSVAL_VOID;
|
||||
|
|
|
@ -1127,26 +1127,6 @@ nsINode::DispatchDOMEvent(nsEvent* aEvent,
|
|||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsINode::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsINode::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsEventListenerManager*
|
||||
nsINode::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
|
|
|
@ -567,6 +567,7 @@ GK_ATOM(menuButton, "menu-button")
|
|||
GK_ATOM(menuitem, "menuitem")
|
||||
GK_ATOM(menulist, "menulist")
|
||||
GK_ATOM(menupopup, "menupopup")
|
||||
GK_ATOM(menuseparator, "menuseparator")
|
||||
GK_ATOM(message, "message")
|
||||
GK_ATOM(meta, "meta")
|
||||
GK_ATOM(meter, "meter")
|
||||
|
@ -723,6 +724,7 @@ GK_ATOM(onresize, "onresize")
|
|||
GK_ATOM(onscroll, "onscroll")
|
||||
GK_ATOM(onselect, "onselect")
|
||||
GK_ATOM(onset, "onset")
|
||||
GK_ATOM(onshow, "onshow")
|
||||
GK_ATOM(onsubmit, "onsubmit")
|
||||
GK_ATOM(ontext, "ontext")
|
||||
GK_ATOM(ontouchstart, "ontouchstart")
|
||||
|
|
|
@ -382,6 +382,8 @@ nsWebSocketEstablishedConnection::Close()
|
|||
|
||||
if (mOwner->mReadyState == nsIMozWebSocket::CONNECTING) {
|
||||
mOwner->SetReadyState(nsIMozWebSocket::CLOSED);
|
||||
mWebSocketChannel->Close(mOwner->mClientReasonCode,
|
||||
mOwner->mClientReason);
|
||||
Disconnect();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1494,7 +1496,7 @@ nsWebSocketEstablishedConnection::GetStatus(nsresult *aStatus)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// probably means window went away or stop button pressed
|
||||
// Window closed, stop/reload button pressed, user navigated away from page, etc.
|
||||
NS_IMETHODIMP
|
||||
nsWebSocketEstablishedConnection::Cancel(nsresult aStatus)
|
||||
{
|
||||
|
|
|
@ -501,6 +501,8 @@ _TEST_FILES2 = \
|
|||
delayedServerEvents.sjs \
|
||||
test_bug664916.html \
|
||||
test_bug666604.html \
|
||||
test_bug675121.html \
|
||||
file_bug675121.sjs \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
var timer;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("Responded");
|
||||
response.processAsync();
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function() {
|
||||
response.finish();
|
||||
// 50ms certainly be enough for one refresh driver firing to happen!
|
||||
}, 50, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=675121
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 675121</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<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=675121">Mozilla Bug 675121</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 675121 **/
|
||||
var callbackFired = false;
|
||||
var xhrInProgress = false;
|
||||
function f() {
|
||||
callbackFired = true;
|
||||
if (!xhrInProgress) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
window.mozRequestAnimationFrame(f);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "file_bug675121.sjs", false);
|
||||
xhrInProgress = true;
|
||||
xhr.send();
|
||||
xhrInProgress = false;
|
||||
is(xhr.responseText, "Responded", "Should have a response by now");
|
||||
is(callbackFired, false, "Callback should not fire during sync XHR");
|
||||
|
||||
if (!callbackFired) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -162,7 +162,7 @@ JSValToDashArray(JSContext* cx, const jsval& patternArray,
|
|||
}
|
||||
|
||||
bool haveNonzeroElement = false;
|
||||
for (jsint i = 0; i < jsint(length); ++i) {
|
||||
for (uint32 i = 0; i < length; ++i) {
|
||||
jsval elt;
|
||||
double d;
|
||||
if (!JS_GetElement(cx, obj, i, &elt)) {
|
||||
|
|
|
@ -53,6 +53,7 @@ EXPORTS = \
|
|||
nsPLDOMEvent.h \
|
||||
nsEventDispatcher.h \
|
||||
nsEventStates.h \
|
||||
nsEventNameList.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
|
|
|
@ -0,0 +1,751 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Boris Zbarsky <bzbarsky@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* This file contains the list of event names that are exposed via IDL
|
||||
* on various objects. It is designed to be used as inline input to
|
||||
* various consumers through the magic of C preprocessing.
|
||||
*
|
||||
* Each entry consists of 4 pieces of information:
|
||||
* 1) The name of the event
|
||||
* 2) The event ID (see nsGUIEvent.h)
|
||||
* 3) The event type (see the EventNameType enum in nsContentUtils.h)
|
||||
* 4) The event struct type for this event.
|
||||
* Items 2-4 might be empty strings for events for which they don't make sense.
|
||||
*
|
||||
* Event names that are exposed as content attributes on HTML elements
|
||||
* and as IDL attributes on Elements, Documents and Windows and have
|
||||
* no forwarding behavior should be enclosed in the EVENT macro.
|
||||
*
|
||||
* Event names that are exposed as content attributes on HTML elements
|
||||
* and as IDL attributes on Elements, Documents and Windows and are
|
||||
* forwarded from <body> and <frameset> to the Window should be
|
||||
* enclosed in the FORWARDED_EVENT macro. If this macro is not
|
||||
* defined, it will be defined to be equivalent to EVENT.
|
||||
*
|
||||
* Event names that are exposed as IDL attributes on Windows only
|
||||
* should be enclosed in the WINDOW_ONLY_EVENT macro. If this macro
|
||||
* is not defined, it will be defined to the empty string.
|
||||
*
|
||||
* Event names that are exposed as content and IDL attributes on
|
||||
* <body> and <frameset>, which forward them to the Window, and are
|
||||
* exposed as IDL attributes on the Window should be enclosed in the
|
||||
* WINDOW_EVENT macro. If this macro is not defined, it will be
|
||||
* defined to be equivalent to WINDOW_ONLY_EVENT.
|
||||
*
|
||||
* Touch-specific event names should be enclosed in TOUCH_EVENT. They
|
||||
* are otherwise equivalent to those enclosed in EVENT. If
|
||||
* TOUCH_EVENT is not defined, it will be defined to the empty string.
|
||||
*
|
||||
* Event names that are not exposed as IDL attributes at all should be
|
||||
* enclosed in NON_IDL_EVENT. If NON_IDL_EVENT is not defined, it
|
||||
* will be defined to the empty string.
|
||||
*/
|
||||
|
||||
#ifdef DEFINED_FORWARDED_EVENT
|
||||
#error "Don't define DEFINED_FORWARDED_EVENT"
|
||||
#endif /* DEFINED_FORWARDED_EVENT */
|
||||
|
||||
#ifndef FORWARDED_EVENT
|
||||
#define FORWARDED_EVENT EVENT
|
||||
#define DEFINED_FORWARDED_EVENT
|
||||
#endif /* FORWARDED_EVENT */
|
||||
|
||||
#ifdef DEFINED_WINDOW_ONLY_EVENT
|
||||
#error "Don't define DEFINED_WINDOW_ONLY_EVENT"
|
||||
#endif /* DEFINED_WINDOW_ONLY_EVENT */
|
||||
|
||||
#ifndef WINDOW_ONLY_EVENT
|
||||
#define WINDOW_ONLY_EVENT(_name, _id, _type, _struct)
|
||||
#define DEFINED_WINDOW_ONLY_EVENT
|
||||
#endif /* WINDOW_ONLY_EVENT */
|
||||
|
||||
#ifdef DEFINED_WINDOW_EVENT
|
||||
#error "Don't define DEFINED_WINDOW_EVENT"
|
||||
#endif /* DEFINED_WINDOW_EVENT */
|
||||
|
||||
#ifndef WINDOW_EVENT
|
||||
#define WINDOW_EVENT WINDOW_ONLY_EVENT
|
||||
#define DEFINED_WINDOW_EVENT
|
||||
#endif /* WINDOW_EVENT */
|
||||
|
||||
#ifdef DEFINED_TOUCH_EVENT
|
||||
#error "Don't define DEFINED_TOUCH_EVENT"
|
||||
#endif /* DEFINED_TOUCH_EVENT */
|
||||
|
||||
#ifndef TOUCH_EVENT
|
||||
#define TOUCH_EVENT(_name, _id, _type, _struct)
|
||||
#define DEFINED_TOUCH_EVENT
|
||||
#endif /* TOUCH_EVENT */
|
||||
|
||||
#ifdef DEFINED_NON_IDL_EVENT
|
||||
#error "Don't define DEFINED_NON_IDL_EVENT"
|
||||
#endif /* DEFINED_NON_IDL_EVENT */
|
||||
|
||||
#ifndef NON_IDL_EVENT
|
||||
#define NON_IDL_EVENT(_name, _id, _type, _struct)
|
||||
#define DEFINED_NON_IDL_EVENT
|
||||
#endif /* NON_IDL_EVENT */
|
||||
|
||||
EVENT(abort,
|
||||
NS_IMAGE_ABORT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
|
||||
NS_EVENT)
|
||||
EVENT(canplay,
|
||||
NS_CANPLAY,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(canplaythrough,
|
||||
NS_CANPLAYTHROUGH,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL )
|
||||
EVENT(change,
|
||||
NS_FORM_CHANGE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT )
|
||||
EVENT(click,
|
||||
NS_MOUSE_CLICK,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(contextmenu,
|
||||
NS_CONTEXTMENU,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MOUSE_EVENT)
|
||||
// Not supported yet
|
||||
// EVENT(cuechange)
|
||||
EVENT(dblclick,
|
||||
NS_MOUSE_DOUBLECLICK,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(drag,
|
||||
NS_DRAGDROP_DRAG,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(dragend,
|
||||
NS_DRAGDROP_END,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(dragenter,
|
||||
NS_DRAGDROP_ENTER,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(dragleave,
|
||||
NS_DRAGDROP_LEAVE_SYNTH,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(dragover,
|
||||
NS_DRAGDROP_OVER_SYNTH,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(dragstart,
|
||||
NS_DRAGDROP_START,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(drop,
|
||||
NS_DRAGDROP_DROP,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_DRAG_EVENT)
|
||||
EVENT(durationchange,
|
||||
NS_DURATIONCHANGE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(emptied,
|
||||
NS_EMPTIED,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(ended,
|
||||
NS_ENDED,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(input,
|
||||
NS_FORM_INPUT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_UI_EVENT)
|
||||
EVENT(invalid,
|
||||
NS_FORM_INVALID,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(keydown,
|
||||
NS_KEY_DOWN,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_KEY_EVENT)
|
||||
EVENT(keypress,
|
||||
NS_KEY_PRESS,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_KEY_EVENT)
|
||||
EVENT(keyup,
|
||||
NS_KEY_UP,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_KEY_EVENT)
|
||||
EVENT(loadeddata,
|
||||
NS_LOADEDDATA,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(loadedmetadata,
|
||||
NS_LOADEDMETADATA,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(loadstart,
|
||||
NS_LOADSTART,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(mousedown,
|
||||
NS_MOUSE_BUTTON_DOWN,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(mousemove,
|
||||
NS_MOUSE_MOVE,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(mouseout,
|
||||
NS_MOUSE_EXIT_SYNTH,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(mouseover,
|
||||
NS_MOUSE_ENTER_SYNTH,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
EVENT(mouseup,
|
||||
NS_MOUSE_BUTTON_UP,
|
||||
EventNameType_All,
|
||||
NS_MOUSE_EVENT)
|
||||
// Not supported yet; probably never because "wheel" is a better idea.
|
||||
// EVENT(mousewheel)
|
||||
EVENT(pause,
|
||||
NS_PAUSE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(play,
|
||||
NS_PLAY,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(playing,
|
||||
NS_PLAYING,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(progress,
|
||||
NS_PROGRESS,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(ratechange,
|
||||
NS_RATECHANGE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(readystatechange,
|
||||
NS_READYSTATECHANGE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(reset,
|
||||
NS_FORM_RESET,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(seeked,
|
||||
NS_SEEKED,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(seeking,
|
||||
NS_SEEKING,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(select,
|
||||
NS_FORM_SELECTED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(show,
|
||||
NS_SHOW_EVENT,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT)
|
||||
EVENT(stalled,
|
||||
NS_STALLED,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(submit,
|
||||
NS_FORM_SUBMIT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(suspend,
|
||||
NS_SUSPEND,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(timeupdate,
|
||||
NS_TIMEUPDATE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(volumechange,
|
||||
NS_VOLUMECHANGE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(waiting,
|
||||
NS_WAITING,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
// Gecko-specific extensions that apply to elements
|
||||
EVENT(copy,
|
||||
NS_COPY,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(cut,
|
||||
NS_CUT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(paste,
|
||||
NS_PASTE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(beforescriptexecute,
|
||||
NS_BEFORE_SCRIPT_EXECUTE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
EVENT(afterscriptexecute,
|
||||
NS_AFTER_SCRIPT_EXECUTE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
|
||||
FORWARDED_EVENT(blur,
|
||||
NS_BLUR_CONTENT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_FOCUS_EVENT)
|
||||
FORWARDED_EVENT(error,
|
||||
NS_LOAD_ERROR,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
|
||||
NS_EVENT)
|
||||
FORWARDED_EVENT(focus,
|
||||
NS_FOCUS_CONTENT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_FOCUS_EVENT)
|
||||
FORWARDED_EVENT(load,
|
||||
NS_LOAD,
|
||||
EventNameType_All,
|
||||
NS_EVENT)
|
||||
FORWARDED_EVENT(scroll,
|
||||
NS_SCROLL_EVENT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
|
||||
NS_EVENT_NULL)
|
||||
|
||||
WINDOW_EVENT(afterprint,
|
||||
NS_AFTERPRINT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(beforeprint,
|
||||
NS_BEFOREPRINT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(beforeunload,
|
||||
NS_BEFORE_PAGE_UNLOAD,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(hashchange,
|
||||
NS_HASHCHANGE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(message,
|
||||
NS_MESSAGE,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(offline,
|
||||
NS_OFFLINE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(online,
|
||||
NS_ONLINE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(pagehide,
|
||||
NS_PAGE_HIDE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(pageshow,
|
||||
NS_PAGE_SHOW,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(popstate,
|
||||
NS_POPSTATE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_EVENT_NULL)
|
||||
// Not supported yet
|
||||
// WINDOW_EVENT(redo)
|
||||
WINDOW_EVENT(resize,
|
||||
NS_RESIZE_EVENT,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
|
||||
NS_EVENT)
|
||||
// Not supported yet
|
||||
// WINDOW_EVENT(storage)
|
||||
// Not supported yet
|
||||
// WINDOW_EVENT(undo)
|
||||
WINDOW_EVENT(unload,
|
||||
NS_PAGE_UNLOAD,
|
||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
|
||||
NS_EVENT)
|
||||
|
||||
WINDOW_ONLY_EVENT(devicemotion,
|
||||
NS_DEVICE_MOTION,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
WINDOW_ONLY_EVENT(deviceorientation,
|
||||
NS_DEVICE_ORIENTATION,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
|
||||
TOUCH_EVENT(touchstart,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT)
|
||||
TOUCH_EVENT(touchend,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT)
|
||||
TOUCH_EVENT(touchmove,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT )
|
||||
TOUCH_EVENT(touchenter,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT )
|
||||
TOUCH_EVENT(touchleave,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT)
|
||||
TOUCH_EVENT(touchcancel,
|
||||
NS_USER_DEFINED_EVENT,
|
||||
EventNameType_All,
|
||||
NS_INPUT_EVENT)
|
||||
|
||||
NON_IDL_EVENT(MozMouseHittest,
|
||||
NS_MOUSE_MOZHITTEST,
|
||||
EventNameType_None,
|
||||
NS_MOUSE_EVENT)
|
||||
|
||||
NON_IDL_EVENT(DOMAttrModified,
|
||||
NS_MUTATION_ATTRMODIFIED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMCharacterDataModified,
|
||||
NS_MUTATION_CHARACTERDATAMODIFIED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMNodeInserted,
|
||||
NS_MUTATION_NODEINSERTED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMNodeRemoved,
|
||||
NS_MUTATION_NODEREMOVED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMNodeInsertedIntoDocument,
|
||||
NS_MUTATION_NODEINSERTEDINTODOCUMENT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMNodeRemovedFromDocument,
|
||||
NS_MUTATION_NODEREMOVEDFROMDOCUMENT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
NON_IDL_EVENT(DOMSubtreeModified,
|
||||
NS_MUTATION_SUBTREEMODIFIED,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MUTATION_EVENT)
|
||||
|
||||
NON_IDL_EVENT(DOMActivate,
|
||||
NS_UI_ACTIVATE,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_UI_EVENT)
|
||||
NON_IDL_EVENT(DOMFocusIn,
|
||||
NS_UI_FOCUSIN,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_UI_EVENT)
|
||||
NON_IDL_EVENT(DOMFocusOut,
|
||||
NS_UI_FOCUSOUT,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_UI_EVENT)
|
||||
|
||||
NON_IDL_EVENT(DOMMouseScroll,
|
||||
NS_MOUSE_SCROLL,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MOUSE_SCROLL_EVENT)
|
||||
NON_IDL_EVENT(MozMousePixelScroll,
|
||||
NS_MOUSE_PIXEL_SCROLL,
|
||||
EventNameType_HTMLXUL,
|
||||
NS_MOUSE_SCROLL_EVENT)
|
||||
|
||||
NON_IDL_EVENT(MozBeforeResize,
|
||||
NS_BEFORERESIZE_EVENT,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
NON_IDL_EVENT(open,
|
||||
NS_OPEN,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
|
||||
// Events that only have on* attributes on XUL elements
|
||||
NON_IDL_EVENT(text,
|
||||
NS_TEXT_TEXT,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(compositionstart,
|
||||
NS_COMPOSITION_START,
|
||||
EventNameType_XUL,
|
||||
NS_COMPOSITION_EVENT)
|
||||
NON_IDL_EVENT(compositionend,
|
||||
NS_COMPOSITION_END,
|
||||
EventNameType_XUL,
|
||||
NS_COMPOSITION_EVENT)
|
||||
NON_IDL_EVENT(command,
|
||||
NS_XUL_COMMAND,
|
||||
EventNameType_XUL,
|
||||
NS_INPUT_EVENT)
|
||||
NON_IDL_EVENT(close,
|
||||
NS_XUL_CLOSE,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(popupshowing,
|
||||
NS_XUL_POPUP_SHOWING,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(popupshown,
|
||||
NS_XUL_POPUP_SHOWN,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(popuphiding,
|
||||
NS_XUL_POPUP_HIDING,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(popuphidden,
|
||||
NS_XUL_POPUP_HIDDEN,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(broadcast,
|
||||
NS_XUL_BROADCAST,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(commandupdate,
|
||||
NS_XUL_COMMAND_UPDATE,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(dragexit,
|
||||
NS_DRAGDROP_EXIT_SYNTH,
|
||||
EventNameType_XUL,
|
||||
NS_DRAG_EVENT)
|
||||
NON_IDL_EVENT(dragdrop,
|
||||
NS_DRAGDROP_DRAGDROP,
|
||||
EventNameType_XUL,
|
||||
NS_DRAG_EVENT)
|
||||
NON_IDL_EVENT(draggesture,
|
||||
NS_DRAGDROP_GESTURE,
|
||||
EventNameType_XUL,
|
||||
NS_DRAG_EVENT)
|
||||
NON_IDL_EVENT(overflow,
|
||||
NS_SCROLLPORT_OVERFLOW,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(underflow,
|
||||
NS_SCROLLPORT_UNDERFLOW,
|
||||
EventNameType_XUL,
|
||||
NS_EVENT_NULL)
|
||||
|
||||
// Various SVG events
|
||||
NON_IDL_EVENT(SVGLoad,
|
||||
NS_SVG_LOAD,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
NON_IDL_EVENT(SVGUnload,
|
||||
NS_SVG_UNLOAD,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
NON_IDL_EVENT(SVGAbort,
|
||||
NS_SVG_ABORT,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
NON_IDL_EVENT(SVGError,
|
||||
NS_SVG_ERROR,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
NON_IDL_EVENT(SVGResize,
|
||||
NS_SVG_RESIZE,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
NON_IDL_EVENT(SVGScroll,
|
||||
NS_SVG_SCROLL,
|
||||
EventNameType_None,
|
||||
NS_SVG_EVENT)
|
||||
|
||||
NON_IDL_EVENT(SVGZoom,
|
||||
NS_SVG_ZOOM,
|
||||
EventNameType_None,
|
||||
NS_SVGZOOM_EVENT)
|
||||
// This is a bit hackish, but SVG's event names are weird.
|
||||
NON_IDL_EVENT(zoom,
|
||||
NS_SVG_ZOOM,
|
||||
EventNameType_SVGSVG,
|
||||
NS_EVENT_NULL)
|
||||
#ifdef MOZ_SMIL
|
||||
NON_IDL_EVENT(begin,
|
||||
NS_SMIL_BEGIN,
|
||||
EventNameType_SMIL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(beginEvent,
|
||||
NS_SMIL_BEGIN,
|
||||
EventNameType_None,
|
||||
NS_SMIL_TIME_EVENT)
|
||||
NON_IDL_EVENT(end,
|
||||
NS_SMIL_END,
|
||||
EventNameType_SMIL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(endEvent,
|
||||
NS_SMIL_END,
|
||||
EventNameType_None,
|
||||
NS_SMIL_TIME_EVENT)
|
||||
NON_IDL_EVENT(repeat,
|
||||
NS_SMIL_REPEAT,
|
||||
EventNameType_SMIL,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(repeatEvent,
|
||||
NS_SMIL_REPEAT,
|
||||
EventNameType_None,
|
||||
NS_SMIL_TIME_EVENT)
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
NON_IDL_EVENT(MozAudioAvailable,
|
||||
NS_MOZAUDIOAVAILABLE,
|
||||
EventNameType_None,
|
||||
NS_EVENT_NULL)
|
||||
NON_IDL_EVENT(MozAfterPaint,
|
||||
NS_AFTERPAINT,
|
||||
EventNameType_None,
|
||||
NS_EVENT)
|
||||
NON_IDL_EVENT(MozBeforePaint,
|
||||
NS_BEFOREPAINT,
|
||||
EventNameType_None,
|
||||
NS_EVENT_NULL)
|
||||
|
||||
NON_IDL_EVENT(MozScrolledAreaChanged,
|
||||
NS_SCROLLEDAREACHANGED,
|
||||
EventNameType_None,
|
||||
NS_SCROLLAREA_EVENT)
|
||||
|
||||
// Simple gesture events
|
||||
NON_IDL_EVENT(MozSwipeGesture,
|
||||
NS_SIMPLE_GESTURE_SWIPE,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozMagnifyGestureStart,
|
||||
NS_SIMPLE_GESTURE_MAGNIFY_START,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozMagnifyGestureUpdate,
|
||||
NS_SIMPLE_GESTURE_MAGNIFY_UPDATE,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozMagnifyGesture,
|
||||
NS_SIMPLE_GESTURE_MAGNIFY,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozRotateGestureStart,
|
||||
NS_SIMPLE_GESTURE_ROTATE_START,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozRotateGestureUpdate,
|
||||
NS_SIMPLE_GESTURE_ROTATE_UPDATE,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozRotateGesture,
|
||||
NS_SIMPLE_GESTURE_ROTATE,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozTapGesture,
|
||||
NS_SIMPLE_GESTURE_TAP,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
NON_IDL_EVENT(MozPressTapGesture,
|
||||
NS_SIMPLE_GESTURE_PRESSTAP,
|
||||
EventNameType_None,
|
||||
NS_SIMPLE_GESTURE_EVENT)
|
||||
|
||||
NON_IDL_EVENT(MozTouchDown,
|
||||
NS_MOZTOUCH_DOWN,
|
||||
EventNameType_None,
|
||||
NS_MOZTOUCH_EVENT)
|
||||
NON_IDL_EVENT(MozTouchMove,
|
||||
NS_MOZTOUCH_MOVE,
|
||||
EventNameType_None,
|
||||
NS_MOZTOUCH_EVENT)
|
||||
NON_IDL_EVENT(MozTouchUp,
|
||||
NS_MOZTOUCH_UP,
|
||||
EventNameType_None,
|
||||
NS_MOZTOUCH_EVENT)
|
||||
|
||||
NON_IDL_EVENT(transitionend,
|
||||
NS_TRANSITION_END,
|
||||
EventNameType_None,
|
||||
NS_TRANSITION_EVENT)
|
||||
NON_IDL_EVENT(animationstart,
|
||||
NS_ANIMATION_START,
|
||||
EventNameType_None,
|
||||
NS_ANIMATION_EVENT)
|
||||
NON_IDL_EVENT(animationend,
|
||||
NS_ANIMATION_END,
|
||||
EventNameType_None,
|
||||
NS_ANIMATION_EVENT)
|
||||
NON_IDL_EVENT(animationiteration,
|
||||
NS_ANIMATION_ITERATION,
|
||||
EventNameType_None,
|
||||
NS_ANIMATION_EVENT)
|
||||
|
||||
#ifdef DEFINED_FORWARDED_EVENT
|
||||
#undef DEFINED_FORWARDED_EVENT
|
||||
#undef FORWARDED_EVENT
|
||||
#endif /* DEFINED_FORWARDED_EVENT */
|
||||
|
||||
#ifdef DEFINED_WINDOW_EVENT
|
||||
#undef DEFINED_WINDOW_EVENT
|
||||
#undef WINDOW_EVENT
|
||||
#endif /* DEFINED_WINDOW_EVENT */
|
||||
|
||||
#ifdef DEFINED_WINDOW_ONLY_EVENT
|
||||
#undef DEFINED_WINDOW_ONLY_EVENT
|
||||
#undef WINDOW_ONLY_EVENT
|
||||
#endif /* DEFINED_WINDOW_ONLY_EVENT */
|
||||
|
||||
#ifdef DEFINED_TOUCH_EVENT
|
||||
#undef DEFINED_TOUCH_EVENT
|
||||
#undef TOUCH_EVENT
|
||||
#endif /* DEFINED_TOUCH_EVENT */
|
||||
|
||||
#ifdef DEFINED_NON_IDL_EVENT
|
||||
#undef DEFINED_NON_IDL_EVENT
|
||||
#undef NON_IDL_EVENT
|
||||
#endif /* DEFINED_NON_IDL_EVENT */
|
||||
|
|
@ -77,7 +77,7 @@ static const char* const sEventNames[] = {
|
|||
"DOMAttrModified", "DOMCharacterDataModified",
|
||||
"DOMActivate", "DOMFocusIn", "DOMFocusOut",
|
||||
"pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
|
||||
"offline", "online", "copy", "cut", "paste", "open", "message",
|
||||
"offline", "online", "copy", "cut", "paste", "open", "message", "show",
|
||||
"SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
|
||||
"SVGZoom",
|
||||
#ifdef MOZ_SMIL
|
||||
|
@ -1257,6 +1257,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_open];
|
||||
case NS_MESSAGE:
|
||||
return sEventNames[eDOMEvents_message];
|
||||
case NS_SHOW_EVENT:
|
||||
return sEventNames[eDOMEvents_show];
|
||||
case NS_SVG_LOAD:
|
||||
return sEventNames[eDOMEvents_SVGLoad];
|
||||
case NS_SVG_UNLOAD:
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
eDOMEvents_paste,
|
||||
eDOMEvents_open,
|
||||
eDOMEvents_message,
|
||||
eDOMEvents_show,
|
||||
eDOMEvents_SVGLoad,
|
||||
eDOMEvents_SVGUnload,
|
||||
eDOMEvents_SVGAbort,
|
||||
|
|
|
@ -206,26 +206,6 @@ nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound)
|
|||
return mListenerManager;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIScriptContext*
|
||||
nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv)
|
||||
{
|
||||
|
|
|
@ -42,16 +42,6 @@
|
|||
#include "nsCaret.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMContextMenuListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMUIListener.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -95,13 +85,9 @@
|
|||
using namespace mozilla::dom;
|
||||
|
||||
#define EVENT_TYPE_EQUALS( ls, type, userType ) \
|
||||
(ls->mEventType && ls->mEventType == type && \
|
||||
(ls->mEventType == type && \
|
||||
(ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
|
||||
|
||||
#define EVENT_TYPE_DATA_EQUALS( type1, type2 ) \
|
||||
(type1 && type2 && type1->iid && type2->iid && \
|
||||
type1->iid->Equals(*(type2->iid)))
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
||||
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
||||
|
@ -138,137 +124,6 @@ MutationBitForEventType(PRUint32 aEventType)
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef
|
||||
NS_STDCALL_FUNCPROTO(nsresult,
|
||||
GenericHandler,
|
||||
nsIDOMEventListener, HandleEvent,
|
||||
(nsIDOMEvent*));
|
||||
|
||||
/*
|
||||
* Things here are not as they appear. Namely, |ifaceListener| below is
|
||||
* not really a pointer to the nsIDOMEventListener interface, and aMethod is
|
||||
* not really a pointer-to-member for nsIDOMEventListener. They both
|
||||
* actually refer to the event-type-specific listener interface. The casting
|
||||
* magic allows us to use a single dispatch method. This relies on the
|
||||
* assumption that nsIDOMEventListener and the event type listener interfaces
|
||||
* have the same object layout and will therefore have compatible
|
||||
* pointer-to-member implementations.
|
||||
*/
|
||||
|
||||
static nsresult DispatchToInterface(nsIDOMEvent* aEvent,
|
||||
nsIDOMEventListener* aListener,
|
||||
GenericHandler aMethod,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsIDOMEventListener* ifaceListener = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
aListener->QueryInterface(aIID, (void**) &ifaceListener);
|
||||
NS_WARN_IF_FALSE(ifaceListener,
|
||||
"DispatchToInterface couldn't QI to the right interface");
|
||||
if (ifaceListener) {
|
||||
rv = (ifaceListener->*aMethod)(aEvent);
|
||||
NS_RELEASE(ifaceListener);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
struct EventDispatchData
|
||||
{
|
||||
PRUint32 message;
|
||||
GenericHandler method;
|
||||
};
|
||||
|
||||
struct EventTypeData
|
||||
{
|
||||
const EventDispatchData* events;
|
||||
int numEvents;
|
||||
const nsIID* iid;
|
||||
};
|
||||
|
||||
#define HANDLER(x) reinterpret_cast<GenericHandler>(x)
|
||||
|
||||
static const EventDispatchData sMouseEvents[] = {
|
||||
{ NS_MOUSE_BUTTON_DOWN, HANDLER(&nsIDOMMouseListener::MouseDown) },
|
||||
{ NS_MOUSE_BUTTON_UP, HANDLER(&nsIDOMMouseListener::MouseUp) },
|
||||
{ NS_MOUSE_CLICK, HANDLER(&nsIDOMMouseListener::MouseClick) },
|
||||
{ NS_MOUSE_DOUBLECLICK, HANDLER(&nsIDOMMouseListener::MouseDblClick) },
|
||||
{ NS_MOUSE_ENTER_SYNTH, HANDLER(&nsIDOMMouseListener::MouseOver) },
|
||||
{ NS_MOUSE_EXIT_SYNTH, HANDLER(&nsIDOMMouseListener::MouseOut) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sMouseMotionEvents[] = {
|
||||
{ NS_MOUSE_MOVE, HANDLER(&nsIDOMMouseMotionListener::MouseMove) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sContextMenuEvents[] = {
|
||||
{ NS_CONTEXTMENU, HANDLER(&nsIDOMContextMenuListener::ContextMenu) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sCompositionEvents[] = {
|
||||
{ NS_COMPOSITION_START,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleStartComposition) },
|
||||
{ NS_COMPOSITION_END,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleEndComposition) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sTextEvents[] = {
|
||||
{ NS_TEXT_TEXT, HANDLER(&nsIDOMTextListener::HandleText) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sKeyEvents[] = {
|
||||
{ NS_KEY_UP, HANDLER(&nsIDOMKeyListener::KeyUp) },
|
||||
{ NS_KEY_DOWN, HANDLER(&nsIDOMKeyListener::KeyDown) },
|
||||
{ NS_KEY_PRESS, HANDLER(&nsIDOMKeyListener::KeyPress) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sFocusEvents[] = {
|
||||
{ NS_FOCUS_CONTENT, HANDLER(&nsIDOMFocusListener::Focus) },
|
||||
{ NS_BLUR_CONTENT, HANDLER(&nsIDOMFocusListener::Blur) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sFormEvents[] = {
|
||||
{ NS_FORM_SUBMIT, HANDLER(&nsIDOMFormListener::Submit) },
|
||||
{ NS_FORM_RESET, HANDLER(&nsIDOMFormListener::Reset) },
|
||||
{ NS_FORM_CHANGE, HANDLER(&nsIDOMFormListener::Change) },
|
||||
{ NS_FORM_SELECTED, HANDLER(&nsIDOMFormListener::Select) },
|
||||
{ NS_FORM_INPUT, HANDLER(&nsIDOMFormListener::Input) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sLoadEvents[] = {
|
||||
{ NS_LOAD, HANDLER(&nsIDOMLoadListener::Load) },
|
||||
{ NS_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::Unload) },
|
||||
{ NS_LOAD_ERROR, HANDLER(&nsIDOMLoadListener::Error) },
|
||||
{ NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sUIEvents[] = {
|
||||
{ NS_UI_ACTIVATE, HANDLER(&nsIDOMUIListener::Activate) },
|
||||
{ NS_UI_FOCUSIN, HANDLER(&nsIDOMUIListener::FocusIn) },
|
||||
{ NS_UI_FOCUSOUT, HANDLER(&nsIDOMUIListener::FocusOut) }
|
||||
};
|
||||
|
||||
#define IMPL_EVENTTYPEDATA(type) \
|
||||
{ \
|
||||
s##type##Events, \
|
||||
NS_ARRAY_LENGTH(s##type##Events), \
|
||||
&NS_GET_IID(nsIDOM##type##Listener) \
|
||||
}
|
||||
|
||||
// IMPORTANT: indices match up with eEventArrayType_ enum values
|
||||
|
||||
static const EventTypeData sEventTypes[] = {
|
||||
IMPL_EVENTTYPEDATA(Mouse),
|
||||
IMPL_EVENTTYPEDATA(MouseMotion),
|
||||
IMPL_EVENTTYPEDATA(ContextMenu),
|
||||
IMPL_EVENTTYPEDATA(Key),
|
||||
IMPL_EVENTTYPEDATA(Load),
|
||||
IMPL_EVENTTYPEDATA(Focus),
|
||||
IMPL_EVENTTYPEDATA(Form),
|
||||
IMPL_EVENTTYPEDATA(Text),
|
||||
IMPL_EVENTTYPEDATA(Composition),
|
||||
IMPL_EVENTTYPEDATA(UI)
|
||||
};
|
||||
|
||||
PRUint32 nsEventListenerManager::sCreatedCount = 0;
|
||||
|
||||
nsEventListenerManager::nsEventListenerManager(nsISupports* aTarget) :
|
||||
|
@ -333,33 +188,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsEventListenerManager)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
||||
const EventTypeData*
|
||||
nsEventListenerManager::GetTypeDataForIID(const nsIID& aIID)
|
||||
{
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) {
|
||||
if (aIID.Equals(*(sEventTypes[i].iid))) {
|
||||
return &sEventTypes[i];
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
const EventTypeData*
|
||||
nsEventListenerManager::GetTypeDataForEventName(nsIAtom* aName)
|
||||
{
|
||||
PRUint32 event = nsContentUtils::GetEventId(aName);
|
||||
if (event != NS_USER_DEFINED_EVENT) {
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) {
|
||||
for (PRInt32 j = 0; j < sEventTypes[i].numEvents; ++j) {
|
||||
if (event == sEventTypes[i].events[j].message) {
|
||||
return &sEventTypes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPIDOMWindow*
|
||||
nsEventListenerManager::GetInnerWindowForTarget()
|
||||
{
|
||||
|
@ -385,38 +213,19 @@ nsresult
|
|||
nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
|
||||
PRUint32 aType,
|
||||
nsIAtom* aTypeAtom,
|
||||
const EventTypeData* aTypeData,
|
||||
PRInt32 aFlags)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(aType || aTypeData, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(aType, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = aListener;
|
||||
|
||||
if (!aTypeData) {
|
||||
// If we don't have type data, we can try to QI listener to the right
|
||||
// interface and set mTypeData only if QI succeeds. This way we can save
|
||||
// calls to DispatchToInterface (in HandleEvent) in those cases when QI
|
||||
// would fail.
|
||||
// @see also DispatchToInterface()
|
||||
const EventTypeData* td = GetTypeDataForEventName(aTypeAtom);
|
||||
if (td && td->iid) {
|
||||
nsIDOMEventListener* ifaceListener = nsnull;
|
||||
aListener->QueryInterface(*(td->iid), (void**) &ifaceListener);
|
||||
if (ifaceListener) {
|
||||
aTypeData = td;
|
||||
NS_RELEASE(ifaceListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsListenerStruct* ls;
|
||||
PRUint32 count = mListeners.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
ls = &mListeners.ElementAt(i);
|
||||
if (ls->mListener == aListener && ls->mFlags == aFlags &&
|
||||
(EVENT_TYPE_EQUALS(ls, aType, aTypeAtom) ||
|
||||
EVENT_TYPE_DATA_EQUALS(aTypeData, ls->mTypeData))) {
|
||||
EVENT_TYPE_EQUALS(ls, aType, aTypeAtom)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +239,6 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
|
|||
ls->mTypeAtom = aTypeAtom;
|
||||
ls->mFlags = aFlags;
|
||||
ls->mHandlerIsString = PR_FALSE;
|
||||
ls->mTypeData = aTypeData;
|
||||
|
||||
if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
|
||||
mMayHaveSystemGroupListeners = PR_TRUE;
|
||||
|
@ -491,10 +299,9 @@ void
|
|||
nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
|
||||
PRUint32 aType,
|
||||
nsIAtom* aUserType,
|
||||
const EventTypeData* aTypeData,
|
||||
PRInt32 aFlags)
|
||||
{
|
||||
if (!aListener || !(aType || aTypeData)) {
|
||||
if (!aListener || !aType) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -506,9 +313,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
|
|||
ls = &mListeners.ElementAt(i);
|
||||
if (ls->mListener == aListener &&
|
||||
((ls->mFlags & ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED) == aFlags) &&
|
||||
(EVENT_TYPE_EQUALS(ls, aType, aUserType) ||
|
||||
(!(ls->mEventType) &&
|
||||
EVENT_TYPE_DATA_EQUALS(ls->mTypeData, aTypeData)))) {
|
||||
EVENT_TYPE_EQUALS(ls, aType, aUserType)) {
|
||||
nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
|
||||
mListeners.RemoveElementAt(i);
|
||||
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
|
||||
|
@ -518,33 +323,15 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventListenerManager::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID,
|
||||
PRInt32 aFlags)
|
||||
static inline PRBool
|
||||
ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent)
|
||||
{
|
||||
return AddEventListener(aListener, NS_EVENT_TYPE_NULL, nsnull,
|
||||
GetTypeDataForIID(aIID), aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID,
|
||||
PRInt32 aFlags)
|
||||
{
|
||||
RemoveEventListener(aListener, NS_EVENT_TYPE_NULL, nsnull,
|
||||
GetTypeDataForIID(aIID), aFlags);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEventListenerManager::ListenerCanHandle(nsListenerStruct* aLs,
|
||||
nsEvent* aEvent)
|
||||
{
|
||||
if (aEvent->message == NS_USER_DEFINED_EVENT) {
|
||||
// We don't want to check aLs->mEventType here, bug 276846.
|
||||
return (aEvent->userType && aLs->mTypeAtom == aEvent->userType);
|
||||
}
|
||||
return (aLs->mEventType == aEvent->message);
|
||||
// This is slightly different from EVENT_TYPE_EQUALS in that it returns
|
||||
// true even when aEvent->message == NS_USER_DEFINED_EVENT and
|
||||
// aLs=>mEventType != NS_USER_DEFINED_EVENT as long as the atoms are the same
|
||||
return aEvent->message == NS_USER_DEFINED_EVENT ?
|
||||
(aLs->mTypeAtom == aEvent->userType) :
|
||||
(aLs->mEventType == aEvent->message);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -554,7 +341,7 @@ nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener,
|
|||
{
|
||||
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType);
|
||||
PRUint32 type = nsContentUtils::GetEventId(atom);
|
||||
return AddEventListener(aListener, type, atom, nsnull, aFlags);
|
||||
return AddEventListener(aListener, type, atom, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -564,7 +351,7 @@ nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener
|
|||
{
|
||||
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType);
|
||||
PRUint32 type = nsContentUtils::GetEventId(atom);
|
||||
RemoveEventListener(aListener, type, atom, nsnull, aFlags);
|
||||
RemoveEventListener(aListener, type, atom, aFlags);
|
||||
}
|
||||
|
||||
nsListenerStruct*
|
||||
|
@ -603,7 +390,7 @@ nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
|
|||
rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
|
||||
getter_AddRefs(scriptListener));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
AddEventListener(scriptListener, eventType, aName, nsnull,
|
||||
AddEventListener(scriptListener, eventType, aName,
|
||||
NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
|
||||
|
||||
ls = FindJSEventListener(eventType, aName);
|
||||
|
@ -1078,10 +865,6 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
|
|||
return result;
|
||||
}
|
||||
|
||||
static PRUint32 sLatestEventType = 0;
|
||||
static const EventTypeData* sLatestEventTypeData = nsnull;
|
||||
static const EventDispatchData* sLatestEventDispData = nsnull;
|
||||
|
||||
/**
|
||||
* Causes a check for event listeners and processing by them if they exist.
|
||||
* @param an event listener
|
||||
|
@ -1101,79 +884,39 @@ nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||
aEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
|
||||
const EventTypeData* typeData = nsnull;
|
||||
const EventDispatchData* dispData = nsnull;
|
||||
if (aEvent->message != NS_USER_DEFINED_EVENT) {
|
||||
// Check if this is the same type of event as what a listener manager
|
||||
// handled last time.
|
||||
if (aEvent->message == sLatestEventType) {
|
||||
typeData = sLatestEventTypeData;
|
||||
dispData = sLatestEventDispData;
|
||||
goto found;
|
||||
}
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) {
|
||||
typeData = &sEventTypes[i];
|
||||
for (PRInt32 j = 0; j < typeData->numEvents; ++j) {
|
||||
dispData = &(typeData->events[j]);
|
||||
if (aEvent->message == dispData->message) {
|
||||
sLatestEventType = aEvent->message;
|
||||
sLatestEventTypeData = typeData;
|
||||
sLatestEventDispData = dispData;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
typeData = nsnull;
|
||||
dispData = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
|
||||
nsAutoTObserverArray<nsListenerStruct, 2>::EndLimitedIterator iter(mListeners);
|
||||
nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
|
||||
PRBool hasListener = PR_FALSE;
|
||||
while (iter.HasMore()) {
|
||||
nsListenerStruct* ls = &iter.GetNext();
|
||||
PRBool useTypeInterface =
|
||||
EVENT_TYPE_DATA_EQUALS(ls->mTypeData, typeData);
|
||||
PRBool useGenericInterface =
|
||||
(!useTypeInterface && ListenerCanHandle(ls, aEvent));
|
||||
// Don't fire the listener if it's been removed.
|
||||
// Check that the phase is same in event and event listener.
|
||||
// Handle only trusted events, except when listener permits untrusted events.
|
||||
if (useTypeInterface || useGenericInterface) {
|
||||
if (ls->mListener) {
|
||||
hasListener = PR_TRUE;
|
||||
// XXX The (mFlags & aFlags) test here seems fragile. Shouldn't we
|
||||
// specifically only test the capture/bubble flags.
|
||||
if ((ls->mFlags & aFlags & ~NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(ls->mFlags & NS_EVENT_FLAG_SYSTEM_EVENT) ==
|
||||
(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(NS_IS_TRUSTED_EVENT(aEvent) ||
|
||||
ls->mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED)) {
|
||||
if (!*aDOMEvent) {
|
||||
nsEventDispatcher::CreateEvent(aPresContext, aEvent,
|
||||
EmptyString(), aDOMEvent);
|
||||
}
|
||||
if (*aDOMEvent) {
|
||||
if (ListenerCanHandle(ls, aEvent)) {
|
||||
hasListener = PR_TRUE;
|
||||
// XXX The (mFlags & aFlags) test here seems fragile. Shouldn't we
|
||||
// specifically only test the capture/bubble flags.
|
||||
if ((ls->mFlags & aFlags & ~NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(ls->mFlags & NS_EVENT_FLAG_SYSTEM_EVENT) ==
|
||||
(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(NS_IS_TRUSTED_EVENT(aEvent) ||
|
||||
ls->mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED)) {
|
||||
if (!*aDOMEvent) {
|
||||
nsEventDispatcher::CreateEvent(aPresContext, aEvent,
|
||||
EmptyString(), aDOMEvent);
|
||||
}
|
||||
if (*aDOMEvent) {
|
||||
if (!aEvent->currentTarget) {
|
||||
aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->currentTarget) {
|
||||
aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->currentTarget) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = ls->mListener;
|
||||
if (useTypeInterface) {
|
||||
aPusher->Pop();
|
||||
DispatchToInterface(*aDOMEvent, ls->mListener,
|
||||
dispData->method, *typeData->iid);
|
||||
} else if (useGenericInterface &&
|
||||
aPusher->RePush(aCurrentTarget)) {
|
||||
if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
|
||||
aCurrentTarget, aFlags,
|
||||
aPusher))) {
|
||||
aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
|
||||
}
|
||||
}
|
||||
nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = ls->mListener;
|
||||
if (aPusher->RePush(aCurrentTarget)) {
|
||||
if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
|
||||
aCurrentTarget, aFlags,
|
||||
aPusher))) {
|
||||
aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1267,30 +1010,11 @@ PRBool
|
|||
nsEventListenerManager::HasListenersFor(const nsAString& aEventName)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventName);
|
||||
PRUint32 type = nsContentUtils::GetEventId(atom);
|
||||
|
||||
const EventTypeData* typeData = nsnull;
|
||||
const EventDispatchData* dispData = nsnull;
|
||||
if (type != NS_USER_DEFINED_EVENT) {
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) {
|
||||
typeData = &sEventTypes[i];
|
||||
for (PRInt32 j = 0; j < typeData->numEvents; ++j) {
|
||||
dispData = &(typeData->events[j]);
|
||||
if (type == dispData->message) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
typeData = nsnull;
|
||||
dispData = nsnull;
|
||||
}
|
||||
}
|
||||
found:
|
||||
|
||||
PRUint32 count = mListeners.Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsListenerStruct* ls = &mListeners.ElementAt(i);
|
||||
if (ls->mTypeAtom == atom ||
|
||||
EVENT_TYPE_DATA_EQUALS(ls->mTypeData, typeData)) {
|
||||
if (ls->mTypeAtom == atom) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1329,43 +1053,13 @@ nsEventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
|||
PR_TRUE);
|
||||
}
|
||||
}
|
||||
if (ls.mTypeData) {
|
||||
// Handle special event listener interfaces, like nsIDOMFocusListener.
|
||||
for (PRInt32 j = 0; j < ls.mTypeData->numEvents; ++j) {
|
||||
const EventDispatchData* dispData = &(ls.mTypeData->events[j]);
|
||||
const char* eventName = nsDOMEvent::GetEventName(dispData->message);
|
||||
if (eventName) {
|
||||
NS_ConvertASCIItoUTF16 eventType(eventName);
|
||||
nsRefPtr<nsEventListenerInfo> info =
|
||||
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||
allowsUntrusted, systemGroup);
|
||||
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||
aList->AppendObject(info);
|
||||
}
|
||||
}
|
||||
} else if (ls.mEventType == NS_USER_DEFINED_EVENT) {
|
||||
// Handle user defined event types.
|
||||
if (ls.mTypeAtom) {
|
||||
const nsDependentSubstring& eventType =
|
||||
Substring(nsDependentAtomString(ls.mTypeAtom), 2);
|
||||
nsRefPtr<nsEventListenerInfo> info =
|
||||
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||
allowsUntrusted, systemGroup);
|
||||
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||
aList->AppendObject(info);
|
||||
}
|
||||
} else {
|
||||
// Handle normal events.
|
||||
const char* eventName = nsDOMEvent::GetEventName(ls.mEventType);
|
||||
if (eventName) {
|
||||
NS_ConvertASCIItoUTF16 eventType(eventName);
|
||||
nsRefPtr<nsEventListenerInfo> info =
|
||||
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||
allowsUntrusted, systemGroup);
|
||||
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||
aList->AppendObject(info);
|
||||
}
|
||||
}
|
||||
const nsDependentSubstring& eventType =
|
||||
Substring(nsDependentAtomString(ls.mTypeAtom), 2);
|
||||
nsRefPtr<nsEventListenerInfo> info =
|
||||
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||
allowsUntrusted, systemGroup);
|
||||
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||
aList->AppendObject(info);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1377,9 +1071,7 @@ nsEventListenerManager::HasUnloadListeners()
|
|||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsListenerStruct* ls = &mListeners.ElementAt(i);
|
||||
if (ls->mEventType == NS_PAGE_UNLOAD ||
|
||||
ls->mEventType == NS_BEFORE_PAGE_UNLOAD ||
|
||||
(ls->mTypeData && ls->mTypeData->iid &&
|
||||
ls->mTypeData->iid->Equals(NS_GET_IID(nsIDOMLoadListener)))) {
|
||||
ls->mEventType == NS_BEFORE_PAGE_UNLOAD) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ typedef struct {
|
|||
nsCOMPtr<nsIAtom> mTypeAtom;
|
||||
PRUint16 mFlags;
|
||||
PRBool mHandlerIsString;
|
||||
const EventTypeData* mTypeData;
|
||||
} nsListenerStruct;
|
||||
|
||||
/*
|
||||
|
@ -97,10 +96,6 @@ public:
|
|||
* Sets events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID, PRInt32 aFlags);
|
||||
void RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID, PRInt32 aFlags);
|
||||
nsresult AddEventListenerByType(nsIDOMEventListener *aListener,
|
||||
const nsAString& type,
|
||||
PRInt32 aFlags);
|
||||
|
@ -218,17 +213,14 @@ protected:
|
|||
nsresult AddEventListener(nsIDOMEventListener *aListener,
|
||||
PRUint32 aType,
|
||||
nsIAtom* aTypeAtom,
|
||||
const EventTypeData* aTypeData,
|
||||
PRInt32 aFlags);
|
||||
void RemoveEventListener(nsIDOMEventListener *aListener,
|
||||
PRUint32 aType,
|
||||
nsIAtom* aUserType,
|
||||
const EventTypeData* aTypeData,
|
||||
PRInt32 aFlags);
|
||||
void RemoveAllListeners();
|
||||
const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
|
||||
const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
|
||||
PRBool ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent);
|
||||
nsPIDOMWindow* GetInnerWindowForTarget();
|
||||
|
||||
PRUint32 mMayHavePaintEventListener : 1;
|
||||
|
|
|
@ -141,6 +141,10 @@
|
|||
|
||||
#ifdef XP_MACOSX
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include "nsCocoaFeatures.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -373,6 +377,7 @@ public:
|
|||
static void OnEvent(nsEvent* aEvent);
|
||||
static void Shutdown();
|
||||
static PRUint32 GetTimeoutTime();
|
||||
static PRUint32 GetGestureTimeoutTime();
|
||||
static PRInt32 AccelerateWheelDelta(PRInt32 aScrollLines,
|
||||
PRBool aIsHorizontal, PRBool aAllowScrollSpeedOverride,
|
||||
nsIScrollableFrame::ScrollUnit *aScrollQuantity,
|
||||
|
@ -382,6 +387,10 @@ public:
|
|||
enum {
|
||||
kScrollSeriesTimeout = 80
|
||||
};
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
static PRBool GetGestureTriggered();
|
||||
static void SetGestureTriggered();
|
||||
#endif
|
||||
protected:
|
||||
static nsIntPoint GetScreenPoint(nsGUIEvent* aEvent);
|
||||
static void OnFailToScrollTarget();
|
||||
|
@ -402,6 +411,9 @@ protected:
|
|||
static PRUint32 sMouseMoved; // in milliseconds
|
||||
static nsITimer* sTimer;
|
||||
static PRInt32 sScrollSeriesCounter;
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
static PRUint32 sGestureTriggered; // in milliseconds
|
||||
#endif
|
||||
};
|
||||
|
||||
nsWeakFrame nsMouseWheelTransaction::sTargetFrame(nsnull);
|
||||
|
@ -409,6 +421,9 @@ PRUint32 nsMouseWheelTransaction::sTime = 0;
|
|||
PRUint32 nsMouseWheelTransaction::sMouseMoved = 0;
|
||||
nsITimer* nsMouseWheelTransaction::sTimer = nsnull;
|
||||
PRInt32 nsMouseWheelTransaction::sScrollSeriesCounter = 0;
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
PRUint32 nsMouseWheelTransaction::sGestureTriggered = 0;
|
||||
#endif
|
||||
|
||||
static PRBool
|
||||
OutOfTime(PRUint32 aBaseTime, PRUint32 aThreshold)
|
||||
|
@ -487,8 +502,29 @@ nsMouseWheelTransaction::EndTransaction()
|
|||
sTimer->Cancel();
|
||||
sTargetFrame = nsnull;
|
||||
sScrollSeriesCounter = 0;
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
sGestureTriggered = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
void
|
||||
nsMouseWheelTransaction::SetGestureTriggered() {
|
||||
sGestureTriggered = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMouseWheelTransaction::GetGestureTriggered() {
|
||||
if (sGestureTriggered != 0 &&
|
||||
OutOfTime(sGestureTriggered, GetGestureTimeoutTime())) {
|
||||
// Start accepting new gestures
|
||||
sGestureTriggered = 0;
|
||||
}
|
||||
|
||||
return sGestureTriggered != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsMouseWheelTransaction::OnEvent(nsEvent* aEvent)
|
||||
{
|
||||
|
@ -634,6 +670,12 @@ nsMouseWheelTransaction::GetScreenPoint(nsGUIEvent* aEvent)
|
|||
return aEvent->refPoint + aEvent->widget->WidgetToScreenOffset();
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsMouseWheelTransaction::GetGestureTimeoutTime()
|
||||
{
|
||||
return Preferences::GetUint("mousewheel.transaction.gesturetimeout", 300);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsMouseWheelTransaction::GetTimeoutTime()
|
||||
{
|
||||
|
@ -2797,6 +2839,22 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
// On lion scroll will trigger back/forward at the edge of the page
|
||||
if (isHorizontal && passToParent && nsCocoaFeatures::OnLionOrLater()) {
|
||||
if (!nsMouseWheelTransaction::GetGestureTriggered()) {
|
||||
if (numLines > 4 || numLines < -4) {
|
||||
DoScrollHistory(-numLines);
|
||||
nsMouseWheelTransaction::SetGestureTriggered();
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// Extend the gesture in progress
|
||||
nsMouseWheelTransaction::SetGestureTriggered();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!passToParent && frameToScroll) {
|
||||
if (aScrollQuantity == nsIScrollableFrame::LINES) {
|
||||
// When this is called for querying the scroll target information,
|
||||
|
|
|
@ -48,6 +48,8 @@ XPIDL_MODULE = content_html
|
|||
XPIDLSRCS = \
|
||||
nsIFormSubmitObserver.idl \
|
||||
nsIPhonetic.idl \
|
||||
nsIHTMLMenu.idl \
|
||||
nsIMenuBuilder.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -12,11 +12,10 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -35,43 +34,40 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
#ifndef nsIDOMMouseMotionListener_h__
|
||||
#define nsIDOMMouseMotionListener_h__
|
||||
interface nsIMenuBuilder;
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
/*
|
||||
* Mouse motion event listener
|
||||
*
|
||||
/**
|
||||
* A private interface.
|
||||
* All methods throw NS_ERROR_DOM_SECURITY_ERR if the caller is not chrome.
|
||||
*/
|
||||
#define NS_IDOMMOUSEMOTIONLISTENER_IID \
|
||||
{ /* 162b3480-ded6-11d1-bd85-00805f8ae3f4 */ \
|
||||
0x162b3480, 0xded6, 0x11d1, \
|
||||
{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
|
||||
|
||||
class nsIDOMMouseMotionListener : public nsIDOMEventListener {
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMMOUSEMOTIONLISTENER_IID)
|
||||
[scriptable, uuid(d3d068d8-e223-4228-ba39-4d6df21ba616)]
|
||||
interface nsIHTMLMenu : nsISupports
|
||||
{
|
||||
/**
|
||||
* Processes a mouse move event
|
||||
* @param aMouseEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
*/
|
||||
NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent) = 0;
|
||||
|
||||
/**
|
||||
* Processes a drag move event
|
||||
* @param aMouseEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
* Creates and dispatches a trusted event named "show".
|
||||
* The event is not cancelable and does not bubble.
|
||||
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#context-menus
|
||||
*/
|
||||
NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent) = 0;
|
||||
void sendShowEvent();
|
||||
|
||||
/**
|
||||
* Creates a native menu builder. The builder type is dependent on menu type.
|
||||
* Currently, it returns nsXULContextMenuBuilder for context menus.
|
||||
* Toolbar menus are not yet supported (the method returns null).
|
||||
*/
|
||||
nsIMenuBuilder createBuilder();
|
||||
|
||||
/*
|
||||
* Builds a menu by iterating over menu children.
|
||||
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#building-menus-and-toolbars
|
||||
* The caller can use a native builder by calling createBuilder() or provide
|
||||
* a custom builder that implements the nsIMenuBuilder interface.
|
||||
* A custom builder can be used for example to build native context menus
|
||||
* that are not defined using <menupopup>.
|
||||
*/
|
||||
void build(in nsIMenuBuilder aBuilder);
|
||||
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMMouseMotionListener,
|
||||
NS_IDOMMOUSEMOTIONLISTENER_IID)
|
||||
|
||||
#endif // nsIDOMMouseMotionListener_h__
|
|
@ -0,0 +1,83 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMHTMLMenuItemElement;
|
||||
|
||||
/**
|
||||
* An interface used to construct native toolbar or context menus from <menu>
|
||||
*/
|
||||
|
||||
[scriptable, uuid(12724737-f7db-43b4-94ab-708a7b86e115)]
|
||||
interface nsIMenuBuilder : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the top level menu or a submenu. The implementation should create
|
||||
* a new context for this menu, so all subsequent methods will add new items
|
||||
* to this newly created menu.
|
||||
*/
|
||||
void openContainer(in DOMString aLabel);
|
||||
|
||||
/**
|
||||
* Add a new menu item. All menu item details can be obtained from
|
||||
* the element. This method is not called for hidden elements or elements
|
||||
* with no or empty label. The icon should be loaded only if aCanLoadIcon
|
||||
* is true.
|
||||
*/
|
||||
void addItemFor(in nsIDOMHTMLMenuItemElement aElement,
|
||||
in boolean aCanLoadIcon);
|
||||
|
||||
/**
|
||||
* Create a new separator.
|
||||
*/
|
||||
void addSeparator();
|
||||
|
||||
/**
|
||||
* Remove last added separator.
|
||||
* Sometimes it's needed to remove last added separator, otherwise it's not
|
||||
* possible to implement the postprocessing in one pass.
|
||||
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#building-menus-and-toolbars
|
||||
*/
|
||||
void undoAddSeparator();
|
||||
|
||||
/**
|
||||
* Set the context to the parent menu.
|
||||
*/
|
||||
void closeContainer();
|
||||
|
||||
};
|
|
@ -82,6 +82,8 @@ CPPSRCS = \
|
|||
nsHTMLLegendElement.cpp \
|
||||
nsHTMLLinkElement.cpp \
|
||||
nsHTMLMapElement.cpp \
|
||||
nsHTMLMenuElement.cpp \
|
||||
nsHTMLMenuItemElement.cpp \
|
||||
nsHTMLMetaElement.cpp \
|
||||
nsHTMLModElement.cpp \
|
||||
nsHTMLObjectElement.cpp \
|
||||
|
@ -134,6 +136,7 @@ INCLUDES += \
|
|||
-I$(srcdir)/../../../base/src \
|
||||
-I$(srcdir)/../../../events/src \
|
||||
-I$(srcdir)/../../../xbl/src \
|
||||
-I$(srcdir)/../../../xul/content/src \
|
||||
-I$(srcdir)/../../../../layout/forms \
|
||||
-I$(srcdir)/../../../../layout/style \
|
||||
-I$(srcdir)/../../../../layout/tables \
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMHTMLMenuElement.h"
|
||||
#include "nsIDOMElementCSSInlineStyle.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
@ -115,6 +116,7 @@
|
|||
#include "nsITextControlElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsHTMLFieldSetElement.h"
|
||||
#include "nsHTMLMenuElement.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
|
@ -2451,6 +2453,28 @@ nsGenericHTMLElement::GetIsContentEditable(PRBool* aContentEditable)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu)
|
||||
{
|
||||
*aContextMenu = nsnull;
|
||||
|
||||
nsAutoString value;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::contextmenu, value);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsRefPtr<nsHTMLMenuElement> element =
|
||||
nsHTMLMenuElement::FromContent(doc->GetElementById(value));
|
||||
element.forget(aContextMenu);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_INT_ATTR(nsGenericHTMLFrameElement, TabIndex, tabindex)
|
||||
|
|
|
@ -66,6 +66,7 @@ struct nsRect;
|
|||
struct nsSize;
|
||||
class nsHTMLFormElement;
|
||||
class nsIDOMDOMStringMap;
|
||||
class nsIDOMHTMLMenuElement;
|
||||
|
||||
typedef nsMappedAttributeElement nsGenericHTMLElementBase;
|
||||
|
||||
|
@ -161,6 +162,7 @@ public:
|
|||
nsresult GetDataset(nsIDOMDOMStringMap** aDataset);
|
||||
// Callback for destructor of of dataset to ensure to null out weak pointer.
|
||||
nsresult ClearDataset();
|
||||
nsresult GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu);
|
||||
|
||||
// Implementation for nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -533,6 +535,11 @@ public:
|
|||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
}
|
||||
|
||||
PRBool IsHidden() const
|
||||
{
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Add/remove this element to the documents name cache
|
||||
|
@ -1471,22 +1478,22 @@ protected:
|
|||
NS_INTERFACE_TABLE_ENTRY(_class, _i10) \
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||
|
||||
/* Use this macro to declare functions that forward the behavior of this interface to another object.
|
||||
This macro doesn't forward Focus or Click because sometimes elements will want to override them. */
|
||||
#define NS_FORWARD_NSIDOMHTMLELEMENT_NOFOCUSCLICK(_to) \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetId(nsAString & aId) { return _to GetId(aId); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetId(const nsAString & aId) { return _to SetId(aId); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetTitle(nsAString & aTitle) { return _to GetTitle(aTitle); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetTitle(const nsAString & aTitle) { return _to SetTitle(aTitle); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetLang(nsAString & aLang) { return _to GetLang(aLang); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetLang(const nsAString & aLang) { return _to SetLang(aLang); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetDir(nsAString & aDir) { return _to GetDir(aDir); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetDir(const nsAString & aDir) { return _to SetDir(aDir); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetClassName(nsAString & aClassName) { return _to GetClassName(aClassName); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetClassName(const nsAString & aClassName) { return _to SetClassName(aClassName); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetAccessKey(nsAString & aAccessKey) { return _to GetAccessKey(aAccessKey); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetAccessKey(const nsAString & aAccessKey) { return _to SetAccessKey(aAccessKey); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetAccessKeyLabel(nsAString & aLabel) { return _to GetAccessKeyLabel(aLabel); } \
|
||||
/* Use this macro to declare functions that forward the behavior of this interface to another object.
|
||||
This macro doesn't forward Focus or Click because sometimes elements will want to override them. */
|
||||
#define NS_FORWARD_NSIDOMHTMLELEMENT_NOFOCUSCLICK(_to) \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetId(nsAString & aId) { return _to GetId(aId); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetId(const nsAString & aId) { return _to SetId(aId); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetTitle(nsAString & aTitle) { return _to GetTitle(aTitle); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetTitle(const nsAString & aTitle) { return _to SetTitle(aTitle); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetLang(nsAString & aLang) { return _to GetLang(aLang); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetLang(const nsAString & aLang) { return _to SetLang(aLang); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetDir(nsAString & aDir) { return _to GetDir(aDir); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetDir(const nsAString & aDir) { return _to SetDir(aDir); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetClassName(nsAString & aClassName) { return _to GetClassName(aClassName); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetClassName(const nsAString & aClassName) { return _to SetClassName(aClassName); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetAccessKey(nsAString & aAccessKey) { return _to GetAccessKey(aAccessKey); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetAccessKey(const nsAString & aAccessKey) { return _to SetAccessKey(aAccessKey); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetAccessKeyLabel(nsAString & aLabel) { return _to GetAccessKeyLabel(aLabel); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD Blur(void) { return _to Blur(); }
|
||||
|
||||
/**
|
||||
|
@ -1563,6 +1570,8 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Label)
|
|||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Legend)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Link)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Map)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(MenuItem)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Object)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup)
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMHTMLMenuItemElement.h"
|
||||
#include "nsXULContextMenuBuilder.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsHTMLMenuItemElement.h"
|
||||
#include "nsHTMLMenuElement.h"
|
||||
|
||||
enum MenuType
|
||||
{
|
||||
MENU_TYPE_CONTEXT = 1,
|
||||
MENU_TYPE_TOOLBAR,
|
||||
MENU_TYPE_LIST
|
||||
};
|
||||
|
||||
static const nsAttrValue::EnumTable kMenuTypeTable[] = {
|
||||
{ "context", MENU_TYPE_CONTEXT },
|
||||
{ "toolbar", MENU_TYPE_TOOLBAR },
|
||||
{ "list", MENU_TYPE_LIST },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const nsAttrValue::EnumTable* kMenuDefaultType =
|
||||
&kMenuTypeTable[2];
|
||||
|
||||
enum SeparatorType
|
||||
{
|
||||
ST_TRUE_INIT = -1,
|
||||
ST_FALSE = 0,
|
||||
ST_TRUE = 1
|
||||
};
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Menu)
|
||||
|
||||
|
||||
nsHTMLMenuElement::nsHTMLMenuElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo), mType(MENU_TYPE_LIST)
|
||||
{
|
||||
}
|
||||
|
||||
nsHTMLMenuElement::~nsHTMLMenuElement()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLMenuElement, nsGenericElement)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLMenuElement, nsGenericElement)
|
||||
|
||||
|
||||
DOMCI_NODE_DATA(HTMLMenuElement, nsHTMLMenuElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLMenuElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLMenuElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLMenuElement,
|
||||
nsIDOMHTMLMenuElement,
|
||||
nsIHTMLMenu)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMenuElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMenuElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(nsHTMLMenuElement)
|
||||
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMenuElement, Compact, compact)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMenuElement, Type, type,
|
||||
kMenuDefaultType->tag)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMenuElement, Label, label)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLMenuElement::SendShowEvent()
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
||||
nsCOMPtr<nsIDocument> document = GetCurrentDoc();
|
||||
if (!document) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsEvent event(PR_TRUE, NS_SHOW_EVENT);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_CANCEL | NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = document->GetShell();
|
||||
if (!shell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsPresContext> presContext = shell->GetPresContext();
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
|
||||
&event, nsnull, &status);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLMenuElement::CreateBuilder(nsIMenuBuilder** _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
||||
*_retval = nsnull;
|
||||
|
||||
if (mType == MENU_TYPE_CONTEXT) {
|
||||
NS_ADDREF(*_retval = new nsXULContextMenuBuilder());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLMenuElement::Build(nsIMenuBuilder* aBuilder)
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
||||
if (!aBuilder) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BuildSubmenu(EmptyString(), this, aBuilder);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsHTMLMenuElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::type) {
|
||||
PRBool success = aResult.ParseEnumValue(aValue, kMenuTypeTable,
|
||||
PR_FALSE);
|
||||
if (success) {
|
||||
mType = aResult.GetEnumValue();
|
||||
} else {
|
||||
mType = kMenuDefaultType->value;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuElement::BuildSubmenu(const nsAString& aLabel,
|
||||
nsIContent* aContent,
|
||||
nsIMenuBuilder* aBuilder)
|
||||
{
|
||||
aBuilder->OpenContainer(aLabel);
|
||||
|
||||
PRInt8 separator = ST_TRUE_INIT;
|
||||
TraverseContent(aContent, aBuilder, separator);
|
||||
|
||||
if (separator == ST_TRUE) {
|
||||
aBuilder->UndoAddSeparator();
|
||||
}
|
||||
|
||||
aBuilder->CloseContainer();
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsHTMLMenuElement::CanLoadIcon(nsIContent* aContent, const nsAString& aIcon)
|
||||
{
|
||||
if (aIcon.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIDocument* doc = aContent->GetOwnerDoc();
|
||||
if (!doc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri), aIcon, doc,
|
||||
baseURI);
|
||||
|
||||
if (!uri) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return nsContentUtils::CanLoadImage(uri, aContent, doc,
|
||||
aContent->NodePrincipal());
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuElement::TraverseContent(nsIContent* aContent,
|
||||
nsIMenuBuilder* aBuilder,
|
||||
PRInt8& aSeparator)
|
||||
{
|
||||
nsCOMPtr<nsIContent> child;
|
||||
for (child = aContent->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
nsGenericHTMLElement* element = nsGenericHTMLElement::FromContent(child);
|
||||
if (!element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIAtom* tag = child->Tag();
|
||||
|
||||
if (tag == nsGkAtoms::menuitem) {
|
||||
nsHTMLMenuItemElement* menuitem =
|
||||
nsHTMLMenuItemElement::FromContent(child);
|
||||
|
||||
if (menuitem->IsHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoString label;
|
||||
menuitem->GetLabel(label);
|
||||
if (label.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoString icon;
|
||||
menuitem->GetIcon(icon);
|
||||
|
||||
aBuilder->AddItemFor(menuitem, CanLoadIcon(child, icon));
|
||||
|
||||
aSeparator = ST_FALSE;
|
||||
} else if (tag == nsGkAtoms::menu && !element->IsHidden()) {
|
||||
if (child->HasAttr(kNameSpaceID_None, nsGkAtoms::label)) {
|
||||
nsAutoString label;
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::label, label);
|
||||
|
||||
BuildSubmenu(label, child, aBuilder);
|
||||
|
||||
aSeparator = ST_FALSE;
|
||||
} else {
|
||||
AddSeparator(aBuilder, aSeparator);
|
||||
|
||||
TraverseContent(child, aBuilder, aSeparator);
|
||||
|
||||
AddSeparator(aBuilder, aSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
nsHTMLMenuElement::AddSeparator(nsIMenuBuilder* aBuilder, PRInt8& aSeparator)
|
||||
{
|
||||
if (aSeparator) {
|
||||
return;
|
||||
}
|
||||
|
||||
aBuilder->AddSeparator();
|
||||
aSeparator = ST_TRUE;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMHTMLMenuElement.h"
|
||||
#include "nsIHTMLMenu.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
|
||||
class nsHTMLMenuElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLMenuElement,
|
||||
public nsIHTMLMenu
|
||||
{
|
||||
public:
|
||||
nsHTMLMenuElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsHTMLMenuElement();
|
||||
|
||||
/** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
|
||||
static nsHTMLMenuElement* FromContent(nsIContent* aContent)
|
||||
{
|
||||
if (aContent && aContent->IsHTML(nsGkAtoms::menu))
|
||||
return static_cast<nsHTMLMenuElement*>(aContent);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLMenuElement
|
||||
NS_DECL_NSIDOMHTMLMENUELEMENT
|
||||
|
||||
// nsIHTMLMenu
|
||||
NS_DECL_NSIHTMLMENU
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
PRUint8 GetType() const { return mType; }
|
||||
|
||||
protected:
|
||||
static PRBool CanLoadIcon(nsIContent* aContent, const nsAString& aIcon);
|
||||
|
||||
void BuildSubmenu(const nsAString& aLabel,
|
||||
nsIContent* aContent,
|
||||
nsIMenuBuilder* aBuilder);
|
||||
|
||||
void TraverseContent(nsIContent* aContent,
|
||||
nsIMenuBuilder* aBuilder,
|
||||
PRInt8& aSeparator);
|
||||
|
||||
void AddSeparator(nsIMenuBuilder* aBuilder, PRInt8& aSeparator);
|
||||
|
||||
PRUint8 mType;
|
||||
};
|
|
@ -0,0 +1,514 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsHTMLMenuItemElement.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// First bits are needed for the menuitem type.
|
||||
#define NS_CHECKED_IS_TOGGLED (1 << 2)
|
||||
#define NS_ORIGINAL_CHECKED_VALUE (1 << 3)
|
||||
#define NS_MENUITEM_TYPE(bits) ((bits) & ~( \
|
||||
NS_CHECKED_IS_TOGGLED | NS_ORIGINAL_CHECKED_VALUE))
|
||||
|
||||
enum CmdType
|
||||
{
|
||||
CMD_TYPE_MENUITEM = 1,
|
||||
CMD_TYPE_CHECKBOX,
|
||||
CMD_TYPE_RADIO
|
||||
};
|
||||
|
||||
static const nsAttrValue::EnumTable kMenuItemTypeTable[] = {
|
||||
{ "menuitem", CMD_TYPE_MENUITEM },
|
||||
{ "checkbox", CMD_TYPE_CHECKBOX },
|
||||
{ "radio", CMD_TYPE_RADIO },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const nsAttrValue::EnumTable* kMenuItemDefaultType =
|
||||
&kMenuItemTypeTable[0];
|
||||
|
||||
// A base class inherited by all radio visitors.
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
Visitor() { }
|
||||
virtual ~Visitor() { }
|
||||
|
||||
/**
|
||||
* Visit a node in the tree. This is meant to be called on all radios in a
|
||||
* group, sequentially. If the method returns false then the iteration is
|
||||
* stopped.
|
||||
*/
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) = 0;
|
||||
};
|
||||
|
||||
// Find the selected radio, see GetSelectedRadio().
|
||||
class GetCheckedVisitor : public Visitor
|
||||
{
|
||||
public:
|
||||
GetCheckedVisitor(nsHTMLMenuItemElement** aResult)
|
||||
: mResult(aResult)
|
||||
{ }
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem)
|
||||
{
|
||||
if (aMenuItem->IsChecked()) {
|
||||
*mResult = aMenuItem;
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
protected:
|
||||
nsHTMLMenuItemElement** mResult;
|
||||
};
|
||||
|
||||
// Deselect all radios except the one passed to the constructor.
|
||||
class ClearCheckedVisitor : public Visitor
|
||||
{
|
||||
public:
|
||||
ClearCheckedVisitor(nsHTMLMenuItemElement* aExcludeMenuItem)
|
||||
: mExcludeMenuItem(aExcludeMenuItem)
|
||||
{ }
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem)
|
||||
{
|
||||
if (aMenuItem != mExcludeMenuItem && aMenuItem->IsChecked()) {
|
||||
aMenuItem->ClearChecked();
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
protected:
|
||||
nsHTMLMenuItemElement* mExcludeMenuItem;
|
||||
};
|
||||
|
||||
// Get current value of the checked dirty flag. The same value is stored on all
|
||||
// radios in the group, so we need to check only the first one.
|
||||
class GetCheckedDirtyVisitor : public Visitor
|
||||
{
|
||||
public:
|
||||
GetCheckedDirtyVisitor(PRBool* aCheckedDirty,
|
||||
nsHTMLMenuItemElement* aExcludeMenuItem)
|
||||
: mCheckedDirty(aCheckedDirty),
|
||||
mExcludeMenuItem(aExcludeMenuItem)
|
||||
{ }
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem)
|
||||
{
|
||||
if (aMenuItem == mExcludeMenuItem) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
*mCheckedDirty = aMenuItem->IsCheckedDirty();
|
||||
return PR_FALSE;
|
||||
}
|
||||
protected:
|
||||
PRBool* mCheckedDirty;
|
||||
nsHTMLMenuItemElement* mExcludeMenuItem;
|
||||
};
|
||||
|
||||
// Set checked dirty to true on all radios in the group.
|
||||
class SetCheckedDirtyVisitor : public Visitor
|
||||
{
|
||||
public:
|
||||
SetCheckedDirtyVisitor()
|
||||
{ }
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem)
|
||||
{
|
||||
aMenuItem->SetCheckedDirty();
|
||||
return PR_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
// A helper visitor that is used to combine two operations (visitors) to avoid
|
||||
// iterating over radios twice.
|
||||
class CombinedVisitor : public Visitor
|
||||
{
|
||||
public:
|
||||
CombinedVisitor(Visitor* aVisitor1, Visitor* aVisitor2)
|
||||
: mVisitor1(aVisitor1), mVisitor2(aVisitor2),
|
||||
mContinue1(PR_TRUE), mContinue2(PR_TRUE)
|
||||
{ }
|
||||
virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem)
|
||||
{
|
||||
if (mContinue1) {
|
||||
mContinue1 = mVisitor1->Visit(aMenuItem);
|
||||
}
|
||||
if (mContinue2) {
|
||||
mContinue2 = mVisitor2->Visit(aMenuItem);
|
||||
}
|
||||
return mContinue1 || mContinue2;
|
||||
}
|
||||
protected:
|
||||
Visitor* mVisitor1;
|
||||
Visitor* mVisitor2;
|
||||
PRPackedBool mContinue1;
|
||||
PRPackedBool mContinue2;
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(MenuItem)
|
||||
|
||||
nsHTMLMenuItemElement::nsHTMLMenuItemElement(
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo, FromParser aFromParser)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
mType(kMenuItemDefaultType->value),
|
||||
mParserCreating(false),
|
||||
mShouldInitChecked(false),
|
||||
mCheckedDirty(false),
|
||||
mChecked(false)
|
||||
{
|
||||
mParserCreating = aFromParser;
|
||||
}
|
||||
|
||||
nsHTMLMenuItemElement::~nsHTMLMenuItemElement()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLMenuItemElement, nsGenericElement)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLMenuItemElement, nsGenericElement)
|
||||
|
||||
|
||||
DOMCI_NODE_DATA(HTMLMenuItemElement, nsHTMLMenuItemElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLMenuItemElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLMenuItemElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLMenuItemElement,
|
||||
nsIDOMHTMLCommandElement,
|
||||
nsIDOMHTMLMenuItemElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMenuItemElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMenuItemElement)
|
||||
|
||||
//NS_IMPL_ELEMENT_CLONE(nsHTMLMenuItemElement)
|
||||
nsresult
|
||||
nsHTMLMenuItemElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
{
|
||||
*aResult = nsnull;
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsHTMLMenuItemElement *it = new nsHTMLMenuItemElement(ni.forget(),
|
||||
NOT_FROM_PARSER);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> kungFuDeathGrip = it;
|
||||
nsresult rv = CopyInnerTo(it);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
switch (mType) {
|
||||
case CMD_TYPE_CHECKBOX:
|
||||
case CMD_TYPE_RADIO:
|
||||
if (mCheckedDirty) {
|
||||
// We no longer have our original checked state. Set our
|
||||
// checked state on the clone.
|
||||
it->mCheckedDirty = true;
|
||||
it->mChecked = mChecked;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kungFuDeathGrip.swap(*aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMenuItemElement, Type, type,
|
||||
kMenuItemDefaultType->tag)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMenuItemElement, Label, label)
|
||||
NS_IMPL_URI_ATTR(nsHTMLMenuItemElement, Icon, icon)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, Disabled, disabled)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, DefaultChecked, checked)
|
||||
//NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, Checked, checked)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMenuItemElement, Radiogroup, radiogroup)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLMenuItemElement::GetChecked(PRBool* aChecked)
|
||||
{
|
||||
*aChecked = mChecked;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLMenuItemElement::SetChecked(PRBool aChecked)
|
||||
{
|
||||
PRBool checkedChanged = mChecked != aChecked;
|
||||
|
||||
mChecked = aChecked;
|
||||
|
||||
if (mType == CMD_TYPE_RADIO) {
|
||||
if (checkedChanged) {
|
||||
if (mCheckedDirty) {
|
||||
ClearCheckedVisitor visitor(this);
|
||||
WalkRadioGroup(&visitor);
|
||||
} else {
|
||||
ClearCheckedVisitor visitor1(this);
|
||||
SetCheckedDirtyVisitor visitor2;
|
||||
CombinedVisitor visitor(&visitor1, &visitor2);
|
||||
WalkRadioGroup(&visitor);
|
||||
}
|
||||
} else if (!mCheckedDirty) {
|
||||
SetCheckedDirtyVisitor visitor;
|
||||
WalkRadioGroup(&visitor);
|
||||
}
|
||||
} else {
|
||||
mCheckedDirty = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLMenuItemElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
if (aVisitor.mEvent->message == NS_MOUSE_CLICK) {
|
||||
|
||||
PRBool originalCheckedValue = PR_FALSE;
|
||||
switch (mType) {
|
||||
case CMD_TYPE_CHECKBOX:
|
||||
originalCheckedValue = mChecked;
|
||||
SetChecked(!originalCheckedValue);
|
||||
aVisitor.mItemFlags |= NS_CHECKED_IS_TOGGLED;
|
||||
break;
|
||||
case CMD_TYPE_RADIO:
|
||||
nsCOMPtr<nsIDOMHTMLMenuItemElement> selectedRadio = GetSelectedRadio();
|
||||
aVisitor.mItemData = selectedRadio;
|
||||
|
||||
originalCheckedValue = mChecked;
|
||||
if (!originalCheckedValue) {
|
||||
SetChecked(PR_TRUE);
|
||||
aVisitor.mItemFlags |= NS_CHECKED_IS_TOGGLED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (originalCheckedValue) {
|
||||
aVisitor.mItemFlags |= NS_ORIGINAL_CHECKED_VALUE;
|
||||
}
|
||||
|
||||
// We must cache type because mType may change during JS event.
|
||||
aVisitor.mItemFlags |= mType;
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLMenuItemElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
// Check to see if the event was cancelled.
|
||||
if (aVisitor.mEvent->message == NS_MOUSE_CLICK &&
|
||||
aVisitor.mItemFlags & NS_CHECKED_IS_TOGGLED &&
|
||||
aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
PRBool originalCheckedValue =
|
||||
!!(aVisitor.mItemFlags & NS_ORIGINAL_CHECKED_VALUE);
|
||||
PRUint8 oldType = NS_MENUITEM_TYPE(aVisitor.mItemFlags);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLMenuItemElement> selectedRadio =
|
||||
do_QueryInterface(aVisitor.mItemData);
|
||||
if (selectedRadio) {
|
||||
selectedRadio->SetChecked(PR_TRUE);
|
||||
if (mType != CMD_TYPE_RADIO) {
|
||||
SetChecked(PR_FALSE);
|
||||
}
|
||||
} else if (oldType == CMD_TYPE_CHECKBOX) {
|
||||
SetChecked(originalCheckedValue);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLMenuItemElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && aDocument && mType == CMD_TYPE_RADIO) {
|
||||
AddedToRadioGroup();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLMenuItemElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
PRBool success = aResult.ParseEnumValue(aValue, kMenuItemTypeTable,
|
||||
PR_FALSE);
|
||||
if (success) {
|
||||
mType = aResult.GetEnumValue();
|
||||
} else {
|
||||
mType = kMenuItemDefaultType->value;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::radiogroup) {
|
||||
aResult.ParseAtom(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuItemElement::DoneCreatingElement()
|
||||
{
|
||||
mParserCreating = false;
|
||||
|
||||
if (mShouldInitChecked) {
|
||||
InitChecked();
|
||||
mShouldInitChecked = false;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLMenuItemElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if ((aName == nsGkAtoms::radiogroup || aName == nsGkAtoms::type) &&
|
||||
mType == CMD_TYPE_RADIO &&
|
||||
!mParserCreating) {
|
||||
if (IsInDoc() && GetParent()) {
|
||||
AddedToRadioGroup();
|
||||
}
|
||||
}
|
||||
|
||||
// Checked must be set no matter what type of menuitem it is, since
|
||||
// GetChecked() must reflect the new value
|
||||
if (aName == nsGkAtoms::checked &&
|
||||
!mCheckedDirty) {
|
||||
if (mParserCreating) {
|
||||
mShouldInitChecked = true;
|
||||
} else {
|
||||
InitChecked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuItemElement::WalkRadioGroup(Visitor* aVisitor)
|
||||
{
|
||||
nsIContent* parent = GetParent();
|
||||
if (!parent) {
|
||||
aVisitor->Visit(this);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAttrInfo info1(GetAttrInfo(kNameSpaceID_None,
|
||||
nsGkAtoms::radiogroup));
|
||||
PRBool info1Empty = !info1.mValue || info1.mValue->IsEmptyString();
|
||||
|
||||
for (nsIContent* cur = parent->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextSibling()) {
|
||||
nsHTMLMenuItemElement* menuitem = nsHTMLMenuItemElement::FromContent(cur);
|
||||
|
||||
if (!menuitem || menuitem->GetType() != CMD_TYPE_RADIO) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAttrInfo info2(menuitem->GetAttrInfo(kNameSpaceID_None,
|
||||
nsGkAtoms::radiogroup));
|
||||
PRBool info2Empty = !info2.mValue || info2.mValue->IsEmptyString();
|
||||
|
||||
if (info1Empty != info2Empty ||
|
||||
info1.mValue && info2.mValue && !info1.mValue->Equals(*info2.mValue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!aVisitor->Visit(menuitem)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsHTMLMenuItemElement*
|
||||
nsHTMLMenuItemElement::GetSelectedRadio()
|
||||
{
|
||||
nsHTMLMenuItemElement* result = nsnull;
|
||||
|
||||
GetCheckedVisitor visitor(&result);
|
||||
WalkRadioGroup(&visitor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuItemElement::AddedToRadioGroup()
|
||||
{
|
||||
PRBool checkedDirty = mCheckedDirty;
|
||||
if (mChecked) {
|
||||
ClearCheckedVisitor visitor1(this);
|
||||
GetCheckedDirtyVisitor visitor2(&checkedDirty, this);
|
||||
CombinedVisitor visitor(&visitor1, &visitor2);
|
||||
WalkRadioGroup(&visitor);
|
||||
} else {
|
||||
GetCheckedDirtyVisitor visitor(&checkedDirty, this);
|
||||
WalkRadioGroup(&visitor);
|
||||
}
|
||||
mCheckedDirty = checkedDirty;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMenuItemElement::InitChecked()
|
||||
{
|
||||
PRBool defaultChecked;
|
||||
GetDefaultChecked(&defaultChecked);
|
||||
mChecked = defaultChecked;
|
||||
if (mType == CMD_TYPE_RADIO) {
|
||||
ClearCheckedVisitor visitor(this);
|
||||
WalkRadioGroup(&visitor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMHTMLMenuItemElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
class Visitor;
|
||||
|
||||
class nsHTMLMenuItemElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLMenuItemElement
|
||||
{
|
||||
public:
|
||||
nsHTMLMenuItemElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
mozilla::dom::FromParser aFromParser);
|
||||
virtual ~nsHTMLMenuItemElement();
|
||||
|
||||
/** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
|
||||
static nsHTMLMenuItemElement* FromContent(nsIContent* aContent)
|
||||
{
|
||||
if (aContent && aContent->IsHTML(nsGkAtoms::menuitem)) {
|
||||
return static_cast<nsHTMLMenuItemElement*>(aContent);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLCommandElement
|
||||
NS_DECL_NSIDOMHTMLCOMMANDELEMENT
|
||||
|
||||
// nsIDOMHTMLMenuItemElement
|
||||
NS_DECL_NSIDOMHTMLMENUITEMELEMENT
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
virtual void DoneCreatingElement();
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
PRUint8 GetType() const { return mType; }
|
||||
|
||||
/**
|
||||
* Syntax sugar to make it easier to check for checked and checked dirty
|
||||
*/
|
||||
PRBool IsChecked() const { return mChecked; }
|
||||
PRBool IsCheckedDirty() const { return mCheckedDirty; }
|
||||
|
||||
protected:
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
void WalkRadioGroup(Visitor* aVisitor);
|
||||
|
||||
nsHTMLMenuItemElement* GetSelectedRadio();
|
||||
|
||||
void AddedToRadioGroup();
|
||||
|
||||
void InitChecked();
|
||||
|
||||
friend class ClearCheckedVisitor;
|
||||
friend class SetCheckedDirtyVisitor;
|
||||
|
||||
void ClearChecked() { mChecked = false; }
|
||||
void SetCheckedDirty() { mCheckedDirty = true; }
|
||||
|
||||
private:
|
||||
PRUint8 mType : 2;
|
||||
bool mParserCreating : 1;
|
||||
bool mShouldInitChecked : 1;
|
||||
bool mCheckedDirty : 1;
|
||||
bool mChecked : 1;
|
||||
};
|
|
@ -360,12 +360,6 @@ nsHTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool IsOptGroup(nsIContent *aContent)
|
||||
{
|
||||
return (aContent->NodeInfo()->Equals(nsGkAtoms::optgroup) &&
|
||||
aContent->IsHTML());
|
||||
}
|
||||
|
||||
// If the document is such that recursing over these options gets us
|
||||
// deeper than four levels, there is something terribly wrong with the
|
||||
// world.
|
||||
|
@ -394,7 +388,7 @@ nsHTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions,
|
|||
}
|
||||
|
||||
// Recurse down into optgroups
|
||||
if (IsOptGroup(aOptions)) {
|
||||
if (aOptions->IsHTML(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount++;
|
||||
|
||||
PRUint32 numChildren = aOptions->GetChildCount();
|
||||
|
@ -438,7 +432,7 @@ nsHTMLSelectElement::RemoveOptionsFromListRecurse(nsIContent* aOptions,
|
|||
}
|
||||
|
||||
// Recurse down deeper for options
|
||||
if (mOptGroupCount && IsOptGroup(aOptions)) {
|
||||
if (mOptGroupCount && aOptions->IsHTML(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount--;
|
||||
|
||||
PRUint32 numChildren = aOptions->GetChildCount();
|
||||
|
@ -1873,15 +1867,15 @@ void nsHTMLSelectElement::DispatchContentReset() {
|
|||
static void
|
||||
AddOptionsRecurse(nsIContent* aRoot, nsHTMLOptionCollection* aArray)
|
||||
{
|
||||
nsIContent* child;
|
||||
for(PRUint32 i = 0; (child = aRoot->GetChildAt(i)); ++i) {
|
||||
nsHTMLOptionElement *opt = nsHTMLOptionElement::FromContent(child);
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextSibling()) {
|
||||
nsHTMLOptionElement* opt = nsHTMLOptionElement::FromContent(cur);
|
||||
if (opt) {
|
||||
// If we fail here, then at least we've tried our best
|
||||
aArray->AppendOption(opt);
|
||||
}
|
||||
else if (IsOptGroup(child)) {
|
||||
AddOptionsRecurse(child, aArray);
|
||||
} else if (cur->IsHTML(nsGkAtoms::optgroup)) {
|
||||
AddOptionsRecurse(cur, aArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1969,15 +1963,15 @@ static void
|
|||
VerifyOptionsRecurse(nsIContent* aRoot, PRInt32& aIndex,
|
||||
nsHTMLOptionCollection* aArray)
|
||||
{
|
||||
nsIContent* child;
|
||||
for(PRUint32 i = 0; (child = aRoot->GetChildAt(i)); ++i) {
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> opt = do_QueryInterface(child);
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextSibling()) {
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> opt = do_QueryInterface(cur);
|
||||
if (opt) {
|
||||
NS_ASSERTION(opt == aArray->ItemAsOption(aIndex++),
|
||||
"Options collection broken");
|
||||
}
|
||||
else if (IsOptGroup(child)) {
|
||||
VerifyOptionsRecurse(child, aIndex, aArray);
|
||||
} else if (cur->IsHTML(nsGkAtoms::optgroup)) {
|
||||
VerifyOptionsRecurse(cur, aIndex, aArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "nsIDOMHTMLParamElement.h"
|
||||
#include "nsIDOMHTMLBaseElement.h"
|
||||
#include "nsIDOMHTMLDirectoryElement.h"
|
||||
#include "nsIDOMHTMLMenuElement.h"
|
||||
#include "nsIDOMHTMLQuoteElement.h"
|
||||
#include "nsIDOMHTMLHeadElement.h"
|
||||
#include "nsIDOMHTMLHtmlElement.h"
|
||||
|
@ -59,7 +58,6 @@ class nsHTMLSharedElement : public nsGenericHTMLElement,
|
|||
public nsIDOMHTMLParamElement,
|
||||
public nsIDOMHTMLBaseElement,
|
||||
public nsIDOMHTMLDirectoryElement,
|
||||
public nsIDOMHTMLMenuElement,
|
||||
public nsIDOMHTMLQuoteElement,
|
||||
public nsIDOMHTMLHeadElement,
|
||||
public nsIDOMHTMLHtmlElement
|
||||
|
@ -89,9 +87,6 @@ public:
|
|||
// nsIDOMHTMLDirectoryElement
|
||||
NS_DECL_NSIDOMHTMLDIRECTORYELEMENT
|
||||
|
||||
// nsIDOMHTMLMenuElement
|
||||
// Same as directoryelement
|
||||
|
||||
// nsIDOMHTMLQuoteElement
|
||||
NS_DECL_NSIDOMHTMLQUOTEELEMENT
|
||||
|
||||
|
@ -157,7 +152,6 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLSharedElement, nsGenericElement)
|
|||
DOMCI_DATA(HTMLParamElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLBaseElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLDirectoryElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLMenuElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLQuoteElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLHeadElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLHtmlElement, nsHTMLSharedElement)
|
||||
|
@ -174,9 +168,6 @@ nsHTMLSharedElement::GetClassInfoInternal()
|
|||
if (mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLDirectoryElement_id);
|
||||
}
|
||||
if (mNodeInfo->Equals(nsGkAtoms::menu)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLMenuElement_id);
|
||||
}
|
||||
if (mNodeInfo->Equals(nsGkAtoms::q)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLQuoteElement_id);
|
||||
}
|
||||
|
@ -203,7 +194,6 @@ NS_INTERFACE_TABLE_HEAD(nsHTMLSharedElement)
|
|||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLParamElement, param)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLDirectoryElement, dir)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLMenuElement, menu)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, q)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, blockquote)
|
||||
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLHeadElement, head)
|
||||
|
@ -224,9 +214,6 @@ NS_IMPL_STRING_ATTR(nsHTMLSharedElement, ValueType, valuetype)
|
|||
// nsIDOMHTMLDirectoryElement
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact)
|
||||
|
||||
// nsIDOMHTMLMenuElement
|
||||
//NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact)
|
||||
|
||||
// nsIDOMHTMLQuoteElement
|
||||
NS_IMPL_URI_ATTR(nsHTMLSharedElement, Cite, cite)
|
||||
|
||||
|
@ -275,8 +262,7 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None &&
|
||||
(mNodeInfo->Equals(nsGkAtoms::dir) ||
|
||||
mNodeInfo->Equals(nsGkAtoms::menu))) {
|
||||
mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
return aResult.ParseEnumValue(aValue, kListTypeTable, PR_FALSE);
|
||||
}
|
||||
|
@ -290,7 +276,7 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
}
|
||||
|
||||
static void
|
||||
DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
DirectoryMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(List)) {
|
||||
|
@ -486,8 +472,8 @@ nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|||
nsMapRuleToAttributesFunc
|
||||
nsHTMLSharedElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir) || mNodeInfo->Equals(nsGkAtoms::menu)) {
|
||||
return &DirectoryMenuMapAttributesIntoRule;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
return &DirectoryMapAttributesIntoRule;
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::GetAttributeMappingFunction();
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsTextEditorState.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIView.h"
|
||||
|
@ -65,8 +67,6 @@
|
|||
#include "nsTextEditRules.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
|
||||
#include "nsTextEditorState.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define nsTextEditorState_h__
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
|
|
@ -146,7 +146,6 @@ _TEST_FILES = \
|
|||
test_formSubmission2.html \
|
||||
file_formSubmission_text.txt \
|
||||
file_formSubmission_img.jpg \
|
||||
test_bug418756.html \
|
||||
test_bug421640.html \
|
||||
test_bug424698.html \
|
||||
test_bug428135.xhtml \
|
||||
|
@ -280,6 +279,8 @@ _TEST_FILES = \
|
|||
test_bug674558.html \
|
||||
test_bug583533.html \
|
||||
test_restore_from_parser_fragment.html \
|
||||
test_bug617528.html \
|
||||
test_checked.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=617528
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 617528</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<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=617528">Mozilla Bug 617528</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<menu>
|
||||
<menuitem id="checkbox" type="checkbox" label="Checkbox" checked></menuitem>
|
||||
<menuitem id="radio1" type="radio" label="Radio1" checked></menuitem>
|
||||
<menuitem id="radio2" type="radio" label="Radio2"></menuitem>
|
||||
</menu>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 617528 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
function click(element, preventDefault, checked) {
|
||||
function handleClick(event) {
|
||||
is(this.checked, checked,
|
||||
"checking .checked (" + this.id + ")");
|
||||
if (preventDefault)
|
||||
event.preventDefault();
|
||||
}
|
||||
element.addEventListener("click", handleClick);
|
||||
element.click();
|
||||
element.removeEventListener("click", handleClick);
|
||||
}
|
||||
|
||||
function verify(elements, data) {
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var element = elements[i];
|
||||
is(element.checked, data[i*2],
|
||||
"checking .checked (" + element.id + ")");
|
||||
is(element.defaultChecked, data[i*2+1],
|
||||
'checking .defaultChecked (' + element.id + ")");
|
||||
}
|
||||
}
|
||||
|
||||
var checkbox = document.getElementById("checkbox");
|
||||
click(checkbox, false, false);
|
||||
verify([checkbox], [false, true]);
|
||||
|
||||
click(checkbox, true, true);
|
||||
verify([checkbox], [false, true]);
|
||||
|
||||
var radio1 = document.getElementById("radio1");
|
||||
var radio2 = document.getElementById("radio2");
|
||||
click(radio2, false, true);
|
||||
verify([radio1, radio2], [false, true,
|
||||
true, false]);
|
||||
|
||||
click(radio1, true, true);
|
||||
verify([radio1, radio2], [false, true,
|
||||
true, false]);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -2,26 +2,41 @@
|
|||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=418756
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=617528
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 418756</title>
|
||||
<title>Test for Bug 418756 and 617528</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/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=418756">Mozilla Bug 418756</a>
|
||||
Mozilla bug
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418756">418756</a>
|
||||
and
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=617528">617528</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<form id="f1">
|
||||
</form>
|
||||
<form id="f2">
|
||||
</form>
|
||||
<menu id="m1">
|
||||
</menu>
|
||||
<menu id="m2">
|
||||
</menu>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript; version=1.7">
|
||||
|
||||
/** Test for Bug 418756 **/
|
||||
/** Test for Bug 418756 and 617528 **/
|
||||
let group1;
|
||||
let group2;
|
||||
let group3;
|
||||
|
||||
let tags = ["input", "menuitem"];
|
||||
for each (let tag in tags) {
|
||||
|
||||
function bounce(node) {
|
||||
let n = node.nextSibling;
|
||||
let p = node.parentNode;
|
||||
|
@ -50,13 +65,13 @@ let id = 0;
|
|||
|
||||
// type can be 'c' for 'checkbox' and 'r' for 'radio'
|
||||
function createNode(type, name, checked) {
|
||||
let node = document.createElement("input");
|
||||
let node = document.createElement(tag);
|
||||
node.setAttribute("type", typeMapper[type]);
|
||||
if (checked) {
|
||||
node.setAttribute("checked", "checked");
|
||||
}
|
||||
node.setAttribute("id", type + (++id));
|
||||
node.setAttribute("name", name);
|
||||
node.setAttribute(tag == "input" ? "name" : "radiogroup", name);
|
||||
createdNodes.push(node);
|
||||
return node;
|
||||
}
|
||||
|
@ -97,7 +112,7 @@ cleanup();
|
|||
// effect
|
||||
for each (let type in types) {
|
||||
let n = createNode(type, 'test1', true);
|
||||
$("f1").appendChild(n);
|
||||
$(tag == "input" ? "f1" : "m1").appendChild(n);
|
||||
n.checked = false;
|
||||
n.defaultChecked = false;
|
||||
bounce(n);
|
||||
|
@ -109,23 +124,23 @@ cleanup();
|
|||
|
||||
// Now check that playing with a single radio in a group affects all
|
||||
// other radios in the group (but not radios not in that group)
|
||||
let group1 = [ createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false) ];
|
||||
let group2 = [ createNode('r', 'g2', false),
|
||||
createNode('r', 'g2', false),
|
||||
createNode('r', 'g2', false) ];
|
||||
let group3 = [ createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false) ];
|
||||
group1 = [ createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false) ];
|
||||
group2 = [ createNode('r', 'g2', false),
|
||||
createNode('r', 'g2', false),
|
||||
createNode('r', 'g2', false) ];
|
||||
group3 = [ createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false),
|
||||
createNode('r', 'g1', false) ];
|
||||
for each (let g in group1) {
|
||||
$("f1").appendChild(g);
|
||||
$(tag == "input" ? "f1" : "m1").appendChild(g);
|
||||
}
|
||||
for each (let g in group2) {
|
||||
$("f1").appendChild(g);
|
||||
$(tag == "input" ? "f1" : "m1").appendChild(g);
|
||||
}
|
||||
for each (let g in group3) {
|
||||
$("f2").appendChild(g);
|
||||
$(tag == "input" ? "f2" : "m2").appendChild(g);
|
||||
}
|
||||
|
||||
for each (let n in [1, 2, 3]) {
|
||||
|
@ -335,6 +350,8 @@ for each (let n in [1, 2, 3]) {
|
|||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
|
@ -1021,7 +1021,10 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
|
||||
case eHTMLTag_input:
|
||||
content->DoneCreatingElement();
|
||||
break;
|
||||
|
||||
case eHTMLTag_menuitem:
|
||||
content->DoneCreatingElement();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -73,13 +73,7 @@
|
|||
|
||||
// Event listeners
|
||||
#include "nsEventListenerManager.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMContextMenuListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsAttrName.h"
|
||||
|
||||
#include "nsGkAtoms.h"
|
||||
|
|
|
@ -1070,7 +1070,8 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
|||
// properly (eg form state restoration).
|
||||
if (nodeInfo->NamespaceID() == kNameSpaceID_XHTML) {
|
||||
if (nodeInfo->NameAtom() == nsGkAtoms::input ||
|
||||
nodeInfo->NameAtom() == nsGkAtoms::button) {
|
||||
nodeInfo->NameAtom() == nsGkAtoms::button ||
|
||||
nodeInfo->NameAtom() == nsGkAtoms::menuitem) {
|
||||
content->DoneCreatingElement();
|
||||
} else if (nodeInfo->NameAtom() == nsGkAtoms::head && !mCurrentHead) {
|
||||
mCurrentHead = content;
|
||||
|
|
|
@ -343,7 +343,8 @@ txMozillaXMLOutput::endElement()
|
|||
}
|
||||
} else if (ns == kNameSpaceID_XHTML &&
|
||||
(localName == nsGkAtoms::input ||
|
||||
localName == nsGkAtoms::button)) {
|
||||
localName == nsGkAtoms::button ||
|
||||
localName == nsGkAtoms::menuitem)) {
|
||||
element->DoneCreatingElement();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xul
|
||||
PARALLEL_DIRS = src
|
||||
PARALLEL_DIRS = public src
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
PARALLEL_DIRS += test
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
|
@ -12,11 +11,10 @@
|
|||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
# The Original Code is Mozilla code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# The Initial Developer of the Original Code is Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
@ -35,14 +33,19 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = src build
|
||||
MODULE = xul
|
||||
|
||||
ifdef MOZ_XUL
|
||||
XPIDLSRCS = \
|
||||
nsIXULContextMenuBuilder.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -12,11 +12,10 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -35,36 +34,40 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
#ifndef nsIDOMContextMenuListener_h__
|
||||
#define nsIDOMContextMenuListener_h__
|
||||
interface nsIDOMDocumentFragment;
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
/*
|
||||
* Context menu event listener
|
||||
*
|
||||
/**
|
||||
* An interface for initialization of XUL context menu builder
|
||||
* and for triggering of menuitem actions with assigned identifiers.
|
||||
*/
|
||||
#define NS_IDOMCONTEXTMENULISTENER_IID \
|
||||
{ /* 162b3480-ded6-11d1-bd85-00805f8ae3f7 */ \
|
||||
0x162b3480, 0xded6, 0x11d1, \
|
||||
{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf7} }
|
||||
|
||||
class nsIDOMContextMenuListener : public nsIDOMEventListener {
|
||||
[scriptable, uuid(f0c35053-14cc-4e23-a9db-f9a68fae8375)]
|
||||
interface nsIXULContextMenuBuilder : nsISupports
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMCONTEXTMENULISTENER_IID)
|
||||
/**
|
||||
* Processes a context menu event
|
||||
* @param aContextMenuEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
*/
|
||||
NS_IMETHOD ContextMenu(nsIDOMEvent* aContextMenuEvent) = 0;
|
||||
* Initialize builder before building.
|
||||
*
|
||||
* @param aDocumentFragment the fragment that will be used to append top
|
||||
* level elements
|
||||
*
|
||||
* @param aGeneratedAttrName the name of the attribute that will be used
|
||||
* to mark elements as generated.
|
||||
*
|
||||
* @param aIdentAttrName the name of the attribute that will be used for
|
||||
* menuitem identification.
|
||||
*/
|
||||
void init(in nsIDOMDocumentFragment aDocumentFragment,
|
||||
in AString aGeneratedAttrName,
|
||||
in AString aIdentAttrName);
|
||||
|
||||
/**
|
||||
* Invoke the action of the menuitem with assigned identifier aIdent.
|
||||
*
|
||||
* @param aIdent the menuitem identifier
|
||||
*/
|
||||
void click(in DOMString aIdent);
|
||||
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMContextMenuListener,
|
||||
NS_IDOMCONTEXTMENULISTENER_IID)
|
||||
|
||||
#endif // nsIDOMContextMenuListener_h__
|
|
@ -54,6 +54,7 @@ ifdef MOZ_XUL
|
|||
CPPSRCS += \
|
||||
nsXULElement.cpp \
|
||||
nsXULPopupListener.cpp \
|
||||
nsXULContextMenuBuilder.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,268 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMHTMLMenuItemElement.h"
|
||||
#include "nsXULContextMenuBuilder.h"
|
||||
|
||||
|
||||
nsXULContextMenuBuilder::nsXULContextMenuBuilder()
|
||||
: mCurrentIdent(0)
|
||||
{
|
||||
}
|
||||
|
||||
nsXULContextMenuBuilder::~nsXULContextMenuBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULContextMenuBuilder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULContextMenuBuilder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFragment)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULContextMenuBuilder)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFragment)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCurrentNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULContextMenuBuilder)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULContextMenuBuilder)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULContextMenuBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMenuBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXULContextMenuBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMenuBuilder)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::OpenContainer(const nsAString& aLabel)
|
||||
{
|
||||
if (!mFragment) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!mCurrentNode) {
|
||||
mCurrentNode = mFragment;
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> menu;
|
||||
nsresult rv = CreateElement(nsGkAtoms::menu, getter_AddRefs(menu));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
menu->SetAttr(kNameSpaceID_None, nsGkAtoms::label, aLabel, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIContent> menuPopup;
|
||||
rv = CreateElement(nsGkAtoms::menupopup, getter_AddRefs(menuPopup));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = menu->AppendChildTo(menuPopup, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mCurrentNode->AppendChildTo(menu, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCurrentNode = menuPopup;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement,
|
||||
PRBool aCanLoadIcon)
|
||||
{
|
||||
if (!mFragment) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> menuitem;
|
||||
nsresult rv = CreateElement(nsGkAtoms::menuitem, getter_AddRefs(menuitem));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString type;
|
||||
aElement->GetType(type);
|
||||
if (type.EqualsLiteral("checkbox") || type.EqualsLiteral("radio")) {
|
||||
// The menu is only temporary, so we don't need to handle
|
||||
// the radio type precisely.
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
NS_LITERAL_STRING("checkbox"), PR_FALSE);
|
||||
PRBool checked;
|
||||
aElement->GetChecked(&checked);
|
||||
if (checked) {
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::checked,
|
||||
NS_LITERAL_STRING("true"), PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString label;
|
||||
aElement->GetLabel(label);
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::label, label, PR_FALSE);
|
||||
|
||||
nsAutoString icon;
|
||||
aElement->GetIcon(icon);
|
||||
if (!icon.IsEmpty()) {
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
NS_LITERAL_STRING("menuitem-iconic"), PR_FALSE);
|
||||
if (aCanLoadIcon) {
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::image, icon, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool disabled;
|
||||
aElement->GetDisabled(&disabled);
|
||||
if (disabled) {
|
||||
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
|
||||
NS_LITERAL_STRING("true"), PR_FALSE);
|
||||
}
|
||||
|
||||
nsAutoString ident;
|
||||
ident.AppendInt(mCurrentIdent++);
|
||||
|
||||
menuitem->SetAttr(kNameSpaceID_None, mIdentAttr, ident, PR_FALSE);
|
||||
|
||||
rv = mCurrentNode->AppendChildTo(menuitem, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mElements.AppendObject(aElement);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::AddSeparator()
|
||||
{
|
||||
if (!mFragment) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> menuseparator;
|
||||
nsresult rv = CreateElement(nsGkAtoms::menuseparator,
|
||||
getter_AddRefs(menuseparator));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mCurrentNode->AppendChildTo(menuseparator, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::UndoAddSeparator()
|
||||
{
|
||||
if (!mFragment) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
PRUint32 count = mCurrentNode->GetChildCount();
|
||||
if (!count ||
|
||||
mCurrentNode->GetChildAt(count - 1)->Tag() != nsGkAtoms::menuseparator) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mCurrentNode->RemoveChildAt(count - 1, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::CloseContainer()
|
||||
{
|
||||
if (!mFragment) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (mCurrentNode == mFragment) {
|
||||
mCurrentNode = nsnull;
|
||||
} else {
|
||||
nsIContent* parent = mCurrentNode->GetParent();
|
||||
mCurrentNode = parent->GetParent();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::Init(nsIDOMDocumentFragment* aDocumentFragment,
|
||||
const nsAString& aGeneratedAttrName,
|
||||
const nsAString& aIdentAttrName)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDocumentFragment);
|
||||
|
||||
mFragment = do_QueryInterface(aDocumentFragment);
|
||||
mDocument = mFragment->GetOwnerDocument();
|
||||
mGeneratedAttr = do_GetAtom(aGeneratedAttrName);
|
||||
mIdentAttr = do_GetAtom(aIdentAttrName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULContextMenuBuilder::Click(const nsAString& aIdent)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 idx = nsString(aIdent).ToInteger(&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIDOMHTMLElement> element = mElements.SafeObjectAt(idx);
|
||||
if (element) {
|
||||
element->Click();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag, nsIContent** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(
|
||||
aTag, nsnull, kNameSpaceID_XUL, nsIDOMNode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = NS_NewElement(aResult, kNameSpaceID_XUL, nodeInfo.forget(),
|
||||
mozilla::dom::NOT_FROM_PARSER);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
(*aResult)->SetAttr(kNameSpaceID_None, mGeneratedAttr, EmptyString(),
|
||||
PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -12,11 +12,10 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -35,43 +34,38 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIMenuBuilder.h"
|
||||
#include "nsIXULContextMenuBuilder.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
#ifndef nsIDOMFocusListener_h__
|
||||
#define nsIDOMFocusListener_h__
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
/*
|
||||
* Mouse up/down/move event listener
|
||||
*
|
||||
*/
|
||||
#define NS_IDOMFOCUSLISTENER_IID \
|
||||
{ /* 80974670-ded6-11d1-bd85-00805f8ae3f4 */ \
|
||||
0x80974670, 0xded6, 0x11d1, \
|
||||
{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
|
||||
|
||||
class nsIDOMFocusListener : public nsIDOMEventListener
|
||||
class nsXULContextMenuBuilder : public nsIMenuBuilder,
|
||||
public nsIXULContextMenuBuilder
|
||||
{
|
||||
public:
|
||||
nsXULContextMenuBuilder();
|
||||
virtual ~nsXULContextMenuBuilder();
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMFOCUSLISTENER_IID)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULContextMenuBuilder,
|
||||
nsIMenuBuilder)
|
||||
NS_DECL_NSIMENUBUILDER
|
||||
|
||||
/**
|
||||
* Processes a focus event
|
||||
* @param aMouseEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
*/
|
||||
NS_IMETHOD Focus(nsIDOMEvent* aEvent) = 0;
|
||||
NS_DECL_NSIXULCONTEXTMENUBUILDER
|
||||
|
||||
/**
|
||||
* Processes a blur event
|
||||
* @param aMouseEvent @see nsIDOMEvent.h
|
||||
* @returns whether the event was consumed or ignored. @see nsresult
|
||||
*/
|
||||
NS_IMETHOD Blur(nsIDOMEvent* aEvent) = 0;
|
||||
protected:
|
||||
nsresult CreateElement(nsIAtom* aTag, nsIContent** aResult);
|
||||
|
||||
nsCOMPtr<nsIContent> mFragment;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsIAtom> mGeneratedAttr;
|
||||
nsCOMPtr<nsIAtom> mIdentAttr;
|
||||
|
||||
nsCOMPtr<nsIContent> mCurrentNode;
|
||||
PRInt32 mCurrentIdent;
|
||||
|
||||
nsCOMArray<nsIDOMHTMLElement> mElements;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMFocusListener, NS_IDOMFOCUSLISTENER_IID)
|
||||
|
||||
#endif // nsIDOMFocusListener_h__
|
|
@ -66,13 +66,6 @@
|
|||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMContextMenuListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMXULCommandDispatcher.h"
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMXULCommandDispatcher.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsString.h"
|
||||
|
|
|
@ -42,14 +42,4 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifndef NSS_DISABLE_DBM
|
||||
ifdef MOZ_MORK
|
||||
PARALLEL_DIRS = mdb mork
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_MORKREADER
|
||||
PARALLEL_DIRS += morkreader
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
<html>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is mozilla.org code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1998-1999
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Daniel Howard
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
<body>
|
||||
<h1>
|
||||
<span CLASS=LXRSHORTDESC>
|
||||
mdb/Mork general-purpose database<p>
|
||||
</span>
|
||||
</h1>
|
||||
<span CLASS=LXRLONGDESC>
|
||||
db contains C++ code for the mdb/Mork database which is a low-level,
|
||||
general-purpose and cross-platform file library. It is used to store
|
||||
mail box data, news data and global history data.
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -1,48 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1999
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = mork
|
||||
XPIDL_MODULE = msgmdb
|
||||
|
||||
EXPORTS = mdb.h
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
2569
db/mdb/public/mdb.h
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = mork
|
||||
LIBRARY_NAME = mork
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsMorkModule
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
CPPSRCS = nsMorkFactory.cpp
|
||||
|
||||
EXPORTS = \
|
||||
nsMorkCID.h \
|
||||
nsIMdbFactoryFactory.h \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS = ../src/$(LIB_PREFIX)msgmork_s.$(LIB_SUFFIX)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIMdbFactoryFactory_h__
|
||||
#define nsIMdbFactoryFactory_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
class nsIMdbFactory;
|
||||
|
||||
// 2794D0B7-E740-47a4-91C0-3E4FCB95B806
|
||||
#define NS_IMDBFACTORYFACTORY_IID \
|
||||
{ 0x2794d0b7, 0xe740, 0x47a4, { 0x91, 0xc0, 0x3e, 0x4f, 0xcb, 0x95, 0xb8, 0x6 } }
|
||||
|
||||
// because Mork doesn't support XPCOM, we have to wrap the mdb factory interface
|
||||
// with an interface that gives you an mdb factory.
|
||||
class nsIMdbFactoryService : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFACTORYFACTORY_IID)
|
||||
NS_IMETHOD GetMdbFactory(nsIMdbFactory **aFactory) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFactoryService, NS_IMDBFACTORYFACTORY_IID)
|
||||
|
||||
#endif
|
|
@ -1,88 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMorkCID.h"
|
||||
#include "nsIMdbFactoryFactory.h"
|
||||
#include "mdb.h"
|
||||
|
||||
class nsMorkFactoryService : public nsIMdbFactoryService
|
||||
{
|
||||
public:
|
||||
nsMorkFactoryService() {};
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetMdbFactory(nsIMdbFactory **aFactory);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIMdbFactory> mMdbFactory;
|
||||
};
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMorkFactoryService)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_MORK_CID);
|
||||
|
||||
const mozilla::Module::CIDEntry kMorkCIDs[] = {
|
||||
{ &kNS_MORK_CID, false, NULL, nsMorkFactoryServiceConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
const mozilla::Module::ContractIDEntry kMorkContracts[] = {
|
||||
{ NS_MORK_CONTRACTID, &kNS_MORK_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module kMorkModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kMorkCIDs,
|
||||
kMorkContracts
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsMorkModule) = &kMorkModule;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMorkFactoryService, nsIMdbFactoryService)
|
||||
|
||||
NS_IMETHODIMP nsMorkFactoryService::GetMdbFactory(nsIMdbFactory **aFactory)
|
||||
{
|
||||
if (!mMdbFactory)
|
||||
mMdbFactory = MakeMdbFactory();
|
||||
NS_IF_ADDREF(*aFactory = mMdbFactory);
|
||||
return *aFactory ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = mork
|
||||
LIBRARY_NAME = msgmork_s
|
||||
FORCE_STATIC_LIB=1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
CPPSRCS = \
|
||||
orkinHeap.cpp \
|
||||
morkArray.cpp \
|
||||
morkAtom.cpp \
|
||||
morkAtomMap.cpp \
|
||||
morkAtomSpace.cpp \
|
||||
morkBlob.cpp \
|
||||
morkBuilder.cpp \
|
||||
morkCell.cpp \
|
||||
morkCellObject.cpp \
|
||||
morkCh.cpp \
|
||||
morkConfig.cpp \
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp \
|
||||
morkEnv.cpp \
|
||||
morkFactory.cpp \
|
||||
morkFile.cpp \
|
||||
morkHandle.cpp \
|
||||
morkIntMap.cpp \
|
||||
morkMap.cpp \
|
||||
morkNode.cpp \
|
||||
morkNodeMap.cpp \
|
||||
morkObject.cpp \
|
||||
morkParser.cpp \
|
||||
morkPool.cpp \
|
||||
morkRow.cpp \
|
||||
morkRowCellCursor.cpp \
|
||||
morkRowMap.cpp \
|
||||
morkRowObject.cpp \
|
||||
morkRowSpace.cpp \
|
||||
morkSink.cpp \
|
||||
morkSpace.cpp \
|
||||
morkStore.cpp \
|
||||
morkStream.cpp \
|
||||
morkTable.cpp \
|
||||
morkPortTableCursor.cpp \
|
||||
morkTableRowCursor.cpp \
|
||||
morkThumb.cpp \
|
||||
morkWriter.cpp \
|
||||
morkYarn.cpp \
|
||||
morkBead.cpp \
|
||||
morkProbeMap.cpp \
|
||||
morkZone.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
CPPSRCS += morkSearchRowCursor.cpp
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,249 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _MORK_
|
||||
#define _MORK_ 1
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#include "nscore.h"
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
// { %%%%% begin disable unused param warnings %%%%%
|
||||
#define MORK_USED_1(x) (void)(&x)
|
||||
#define MORK_USED_2(x,y) (void)(&x);(void)(&y);
|
||||
#define MORK_USED_3(x,y,z) (void)(&x);(void)(&y);(void)(&z);
|
||||
#define MORK_USED_4(w,x,y,z) (void)(&w);(void)(&x);(void)(&y);(void)(&z);
|
||||
|
||||
// } %%%%% end disable unused param warnings %%%%%
|
||||
|
||||
// { %%%%% begin macro for finding class member offset %%%%%
|
||||
|
||||
/*| OffsetOf: the unsigned integer offset of a class or struct
|
||||
**| field from the beginning of that class or struct. This is
|
||||
**| the same as the similarly named public domain IronDoc macro,
|
||||
**| and is also the same as another macro appearing in stdlib.h.
|
||||
**| We want these offsets so we can correctly convert pointers
|
||||
**| to member slots back into pointers to enclosing objects, and
|
||||
**| have this exactly match what the compiler thinks is true.
|
||||
**|
|
||||
**|| Bascially we are asking the compiler to determine the offset at
|
||||
**| compile time, and we use the definition of address artithmetic
|
||||
**| to do this. By casting integer zero to a pointer of type obj*,
|
||||
**| we can reference the address of a slot in such an object that
|
||||
**| is hypothetically physically placed at address zero, but without
|
||||
**| actually dereferencing a memory location. The absolute address
|
||||
**| of slot is the same as offset of that slot, when the object is
|
||||
**| placed at address zero.
|
||||
|*/
|
||||
#define mork_OffsetOf(obj,slot) ((unsigned int)&((obj*) 0)->slot)
|
||||
|
||||
// } %%%%% end macro for finding class member offset %%%%%
|
||||
|
||||
// { %%%%% begin specific-size integer scalar typedefs %%%%%
|
||||
typedef unsigned char mork_u1; // make sure this is one byte
|
||||
typedef unsigned short mork_u2; // make sure this is two bytes
|
||||
typedef short mork_i2; // make sure this is two bytes
|
||||
typedef PRUint32 mork_u4; // make sure this is four bytes
|
||||
typedef PRInt32 mork_i4; // make sure this is four bytes
|
||||
typedef PRWord mork_ip; // make sure sizeof(mork_ip) == sizeof(void*)
|
||||
|
||||
typedef mork_u1 mork_ch; // small byte-sized character (never wide)
|
||||
typedef mork_u1 mork_flags; // one byte's worth of predicate bit flags
|
||||
|
||||
typedef mork_u2 mork_base; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_derived; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_uses; // 2-byte strong uses count
|
||||
typedef mork_u2 mork_refs; // 2-byte actual reference count
|
||||
|
||||
typedef mork_u4 mork_token; // unsigned token for atomized string
|
||||
typedef mork_token mork_scope; // token used to id scope for rows
|
||||
typedef mork_token mork_kind; // token used to id kind for tables
|
||||
typedef mork_token mork_cscode; // token used to id charset names
|
||||
typedef mork_token mork_aid; // token used to id atomize cell values
|
||||
|
||||
typedef mork_token mork_column; // token used to id columns for rows
|
||||
typedef mork_column mork_delta; // mork_column plus mork_change
|
||||
|
||||
typedef mork_token mork_color; // bead ID
|
||||
#define morkColor_kNone ((mork_color) 0)
|
||||
|
||||
typedef mork_u4 mork_magic; // unsigned magic signature
|
||||
|
||||
typedef mork_u4 mork_seed; // unsigned collection change counter
|
||||
typedef mork_u4 mork_count; // unsigned collection member count
|
||||
typedef mork_count mork_num; // synonym for count
|
||||
typedef mork_u4 mork_size; // unsigned physical media size
|
||||
typedef mork_u4 mork_fill; // unsigned logical content size
|
||||
typedef mork_u4 mork_more; // more available bytes for larger buffer
|
||||
|
||||
typedef mdb_u4 mork_percent; // 0..100, with values >100 same as 100
|
||||
|
||||
typedef mork_i4 mork_pos; // negative means "before first" (at zero pos)
|
||||
typedef mork_i4 mork_line; // negative means "before first line in file"
|
||||
|
||||
typedef mork_u1 mork_usage; // 1-byte magic usage signature slot in object
|
||||
typedef mork_u1 mork_access; // 1-byte magic access signature slot in object
|
||||
|
||||
typedef mork_u1 mork_change; // add, cut, put, set, nil
|
||||
typedef mork_u1 mork_priority; // 0..9, for a total of ten different values
|
||||
|
||||
typedef mork_u1 mork_able; // on, off, asleep (clone IronDoc's fe_able)
|
||||
typedef mork_u1 mork_load; // dirty or clean (clone IronDoc's fe_load)
|
||||
// } %%%%% end specific-size integer scalar typedefs %%%%%
|
||||
|
||||
// 'test' is a public domain Mithril for key equality tests in probe maps
|
||||
typedef mork_i2 mork_test; /* neg=>kVoid, zero=>kHit, pos=>kMiss */
|
||||
|
||||
#define morkTest_kVoid ((mork_test) -1) /* -1: nil key slot, no key order */
|
||||
#define morkTest_kHit ((mork_test) 0) /* 0: keys are equal, a map hit */
|
||||
#define morkTest_kMiss ((mork_test) 1) /* 1: keys not equal, a map miss */
|
||||
|
||||
// { %%%%% begin constants for Mork scalar types %%%%%
|
||||
#define morkPriority_kHi ((mork_priority) 0) /* best priority */
|
||||
#define morkPriority_kMin ((mork_priority) 0) /* best priority is smallest */
|
||||
|
||||
#define morkPriority_kLo ((mork_priority) 9) /* worst priority */
|
||||
#define morkPriority_kMax ((mork_priority) 9) /* worst priority is biggest */
|
||||
|
||||
#define morkPriority_kCount 10 /* number of distinct priority values */
|
||||
|
||||
#define morkAble_kEnabled ((mork_able) 0x55) /* same as IronDoc constant */
|
||||
#define morkAble_kDisabled ((mork_able) 0xAA) /* same as IronDoc constant */
|
||||
#define morkAble_kAsleep ((mork_able) 0x5A) /* same as IronDoc constant */
|
||||
|
||||
#define morkChange_kAdd 'a' /* add member */
|
||||
#define morkChange_kCut 'c' /* cut member */
|
||||
#define morkChange_kPut 'p' /* put member */
|
||||
#define morkChange_kSet 's' /* set all members */
|
||||
#define morkChange_kNil 0 /* no change in this member */
|
||||
#define morkChange_kDup 'd' /* duplicate changes have no effect */
|
||||
// kDup is intended to replace another change constant in an object as a
|
||||
// conclusion about change feasibility while staging intended alterations.
|
||||
|
||||
#define morkLoad_kDirty ((mork_load) 0xDD) /* same as IronDoc constant */
|
||||
#define morkLoad_kClean ((mork_load) 0x22) /* same as IronDoc constant */
|
||||
|
||||
#define morkAccess_kOpen 'o'
|
||||
#define morkAccess_kClosing 'c'
|
||||
#define morkAccess_kShut 's'
|
||||
#define morkAccess_kDead 'd'
|
||||
// } %%%%% end constants for Mork scalar types %%%%%
|
||||
|
||||
// { %%%%% begin non-specific-size integer scalar typedefs %%%%%
|
||||
typedef int mork_char; // nominal type for ints used to hold input byte
|
||||
#define morkChar_IsWhite(c) \
|
||||
((c) == 0xA || (c) == 0x9 || (c) == 0xD || (c) == ' ')
|
||||
// } %%%%% end non-specific-size integer scalar typedefs %%%%%
|
||||
|
||||
// { %%%%% begin mdb-driven scalar typedefs %%%%%
|
||||
// easier to define bool exactly the same as mdb:
|
||||
typedef mdb_bool mork_bool; // unsigned byte with zero=false, nonzero=true
|
||||
|
||||
/* canonical boolean constants provided only for code clarity: */
|
||||
#define morkBool_kTrue ((mork_bool) 1) /* actually any nonzero means true */
|
||||
#define morkBool_kFalse ((mork_bool) 0) /* only zero means false */
|
||||
|
||||
// mdb clients can assign these, so we cannot pick maximum size:
|
||||
typedef mdb_id mork_id; // unsigned object identity in a scope
|
||||
typedef mork_id mork_rid; // unsigned row identity inside scope
|
||||
typedef mork_id mork_tid; // unsigned table identity inside scope
|
||||
typedef mork_id mork_gid; // unsigned group identity without any scope
|
||||
|
||||
// we only care about neg, zero, pos -- so we don't care about size:
|
||||
typedef mdb_order mork_order; // neg:lessthan, zero:equalto, pos:greaterthan
|
||||
// } %%%%% end mdb-driven scalar typedefs %%%%%
|
||||
|
||||
#define morkId_kMinusOne ((mdb_id) -1)
|
||||
|
||||
// { %%%%% begin class forward defines %%%%%
|
||||
// try to put these in alphabetical order for easier examination:
|
||||
class morkMid;
|
||||
class morkAtom;
|
||||
class morkAtomSpace;
|
||||
class morkBookAtom;
|
||||
class morkBuf;
|
||||
class morkBuilder;
|
||||
class morkCell;
|
||||
class morkCellObject;
|
||||
class morkCursor;
|
||||
class morkEnv;
|
||||
class morkFactory;
|
||||
class morkFile;
|
||||
class morkHandle;
|
||||
class morkHandleFace; // just an opaque cookie type
|
||||
class morkHandleFrame;
|
||||
class morkHashArrays;
|
||||
class morkMap;
|
||||
class morkNode;
|
||||
class morkObject;
|
||||
class morkOidAtom;
|
||||
class morkParser;
|
||||
class morkPool;
|
||||
class morkPlace;
|
||||
class morkPort;
|
||||
class morkPortTableCursor;
|
||||
class morkProbeMap;
|
||||
class morkRow;
|
||||
class morkRowCellCursor;
|
||||
class morkRowObject;
|
||||
class morkRowSpace;
|
||||
class morkSorting;
|
||||
class morkSortingRowCursor;
|
||||
class morkSpace;
|
||||
class morkSpan;
|
||||
class morkStore;
|
||||
class morkStream;
|
||||
class morkTable;
|
||||
class morkTableChange;
|
||||
class morkTableRowCursor;
|
||||
class morkThumb;
|
||||
class morkWriter;
|
||||
class morkZone;
|
||||
// } %%%%% end class forward defines %%%%%
|
||||
|
||||
// include this config file last for platform & environment specific stuff:
|
||||
#ifndef _MORKCONFIG_
|
||||
#include "morkConfig.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORK_ */
|
|
@ -1,334 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkArray::CloseMorkNode(morkEnv* ev) // CloseTable() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseArray(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkArray::~morkArray() // assert CloseTable() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mArray_Slots==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkArray::morkArray(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mArray_Slots( 0 )
|
||||
, mArray_Heap( 0 )
|
||||
, mArray_Fill( 0 )
|
||||
, mArray_Size( 0 )
|
||||
, mArray_Seed( (mork_u4)NS_PTR_TO_INT32(this) ) // "random" integer assignment
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mArray_Heap);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( inSize < 3 )
|
||||
inSize = 3;
|
||||
mdb_size byteSize = inSize * sizeof(void*);
|
||||
void** block = 0;
|
||||
ioSlotHeap->Alloc(ev->AsMdbEnv(), byteSize, (void**) &block);
|
||||
if ( block && ev->Good() )
|
||||
{
|
||||
mArray_Slots = block;
|
||||
mArray_Size = inSize;
|
||||
MORK_MEMSET(mArray_Slots, 0, byteSize);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkArray::CloseArray(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( mArray_Heap && mArray_Slots )
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), mArray_Slots);
|
||||
|
||||
mArray_Slots = 0;
|
||||
mArray_Size = 0;
|
||||
mArray_Fill = 0;
|
||||
++mArray_Seed;
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mArray_Heap);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NonArrayTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkArray");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::IndexBeyondEndError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("array index beyond end");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NilSlotsAddressError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mArray_Slots");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::FillBeyondSizeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mArray_Fill > mArray_Size");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkArray::Grow(morkEnv* ev, mork_size inNewSize)
|
||||
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
|
||||
{
|
||||
if ( ev->Good() && inNewSize > mArray_Size ) // make array larger?
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size ) // fill and size fit the invariant?
|
||||
{
|
||||
if (mArray_Size <= 3)
|
||||
inNewSize = mArray_Size + 3;
|
||||
else
|
||||
inNewSize = mArray_Size * 2;// + 3; // try doubling size here - used to grow by 3
|
||||
|
||||
mdb_size newByteSize = inNewSize * sizeof(void*);
|
||||
void** newBlock = 0;
|
||||
mArray_Heap->Alloc(ev->AsMdbEnv(), newByteSize, (void**) &newBlock);
|
||||
if ( newBlock && ev->Good() ) // okay new block?
|
||||
{
|
||||
void** oldSlots = mArray_Slots;
|
||||
void** oldEnd = oldSlots + mArray_Fill;
|
||||
|
||||
void** newSlots = newBlock;
|
||||
void** newEnd = newBlock + inNewSize;
|
||||
|
||||
while ( oldSlots < oldEnd )
|
||||
*newSlots++ = *oldSlots++;
|
||||
|
||||
while ( newSlots < newEnd )
|
||||
*newSlots++ = (void*) 0;
|
||||
|
||||
oldSlots = mArray_Slots;
|
||||
mArray_Size = inNewSize;
|
||||
mArray_Slots = newBlock;
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), oldSlots);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
++mArray_Seed; // always modify seed, since caller intends to add slots
|
||||
return ( ev->Good() && mArray_Size >= inNewSize );
|
||||
}
|
||||
|
||||
void*
|
||||
morkArray::SafeAt(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
|
||||
return mArray_Slots[ inPos ];
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
|
||||
{
|
||||
mArray_Slots[ inPos ] = ioSlot;
|
||||
++mArray_Seed;
|
||||
}
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
mork_pos
|
||||
morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
|
||||
{
|
||||
mork_pos outPos = -1;
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
outPos = (mork_pos) fill;
|
||||
mArray_Slots[ fill ] = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be added
|
||||
|
||||
while ( --end >= slot ) // another slot to move upward?
|
||||
end[ 1 ] = *end;
|
||||
|
||||
*slot = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion?
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be cut
|
||||
|
||||
while ( ++slot < end ) // another slot to move downward?
|
||||
slot[ -1 ] = *slot;
|
||||
|
||||
slot[ -1 ] = 0; // clear the last used slot which is now unused
|
||||
|
||||
// note inPos<fill implies fill>0, so fill-1 must be nonnegative:
|
||||
mArray_Fill = fill - 1;
|
||||
++mArray_Seed;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutAllSlots(morkEnv* ev)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size )
|
||||
{
|
||||
mdb_size oldByteSize = mArray_Fill * sizeof(void*);
|
||||
MORK_MEMSET(mArray_Slots, 0, oldByteSize);
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
++mArray_Seed;
|
||||
mArray_Fill = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,130 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#define _MORKARRAY_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kArray /*i*/ 0x4179 /* ascii 'Ay' */
|
||||
|
||||
class morkArray : public morkNode { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
void** mArray_Slots; // array of pointers
|
||||
nsIMdbHeap* mArray_Heap; // required heap for allocating mArray_Slots
|
||||
mork_fill mArray_Fill; // logical count of used slots in mArray_Slots
|
||||
mork_size mArray_Size; // physical count of mArray_Slots ( >= Fill)
|
||||
mork_seed mArray_Seed; // change counter for syncing with iterators
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseArray()
|
||||
virtual ~morkArray(); // assert that close executed earlier
|
||||
|
||||
public: // morkArray construction & destruction
|
||||
morkArray(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseArray(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkArray(const morkArray& other);
|
||||
morkArray& operator=(const morkArray& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsArray() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kArray; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing & errors
|
||||
static void NonArrayTypeError(morkEnv* ev);
|
||||
static void IndexBeyondEndError(morkEnv* ev);
|
||||
static void NilSlotsAddressError(morkEnv* ev);
|
||||
static void FillBeyondSizeError(morkEnv* ev);
|
||||
|
||||
public: // other table row cursor methods
|
||||
|
||||
mork_fill Length() const { return mArray_Fill; }
|
||||
mork_size Capacity() const { return mArray_Size; }
|
||||
|
||||
mork_bool Grow(morkEnv* ev, mork_size inNewSize);
|
||||
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
|
||||
|
||||
void* At(mork_pos inPos) const { return mArray_Slots[ inPos ]; }
|
||||
void AtPut(mork_pos inPos, void* ioSlot)
|
||||
{ mArray_Slots[ inPos ] = ioSlot; }
|
||||
|
||||
void* SafeAt(morkEnv* ev, mork_pos inPos);
|
||||
void SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot);
|
||||
|
||||
mork_pos AppendSlot(morkEnv* ev, void* ioSlot);
|
||||
void AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot);
|
||||
void CutSlot(morkEnv* ev, mork_pos inPos);
|
||||
void CutAllSlots(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakArray(morkArray* me,
|
||||
morkEnv* ev, morkArray** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongArray(morkArray* me,
|
||||
morkEnv* ev, morkArray** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTABLEROWCURSOR_ */
|
|
@ -1,604 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
mork_bool
|
||||
morkAtom::GetYarn(mdbYarn* outYarn) const
|
||||
{
|
||||
const void* source = 0;
|
||||
mdb_fill fill = 0;
|
||||
mdb_cscode form = 0;
|
||||
outYarn->mYarn_More = 0;
|
||||
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) this;
|
||||
source = weeBook->mWeeBookAtom_Body;
|
||||
fill = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) this;
|
||||
source = bigBook->mBigBookAtom_Body;
|
||||
fill = bigBook->mBigBookAtom_Size;
|
||||
form = bigBook->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( this->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) this;
|
||||
source = weeAnon->mWeeAnonAtom_Body;
|
||||
fill = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( this->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) this;
|
||||
source = bigAnon->mBigAnonAtom_Body;
|
||||
fill = bigAnon->mBigAnonAtom_Size;
|
||||
form = bigAnon->mBigAnonAtom_Form;
|
||||
}
|
||||
}
|
||||
if ( source && fill ) // have an atom with nonempty content?
|
||||
{
|
||||
// if we have too many bytes, and yarn seems growable:
|
||||
if ( fill > outYarn->mYarn_Size && outYarn->mYarn_Grow ) // try grow?
|
||||
(*outYarn->mYarn_Grow)(outYarn, (mdb_size) fill); // request bigger
|
||||
|
||||
mdb_size size = outYarn->mYarn_Size; // max dest size
|
||||
if ( fill > size ) // too much atom content?
|
||||
{
|
||||
outYarn->mYarn_More = fill - size; // extra atom bytes omitted
|
||||
fill = size; // copy no more bytes than size of yarn buffer
|
||||
}
|
||||
void* dest = outYarn->mYarn_Buf; // where bytes are going
|
||||
if ( !dest ) // nil destination address buffer?
|
||||
fill = 0; // we can't write any content at all
|
||||
|
||||
if ( fill ) // anything to copy?
|
||||
MORK_MEMCPY(dest, source, fill); // copy fill bytes to yarn
|
||||
|
||||
outYarn->mYarn_Fill = fill; // tell yarn size of copied content
|
||||
}
|
||||
else // no content to put into the yarn
|
||||
{
|
||||
outYarn->mYarn_Fill = 0; // tell yarn that atom has no bytes
|
||||
}
|
||||
outYarn->mYarn_Form = form; // always update the form slot
|
||||
|
||||
return ( source != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkAtom::AsBuf(morkBuf& outBuf) const
|
||||
{
|
||||
const morkAtom* atom = this;
|
||||
if ( atom )
|
||||
{
|
||||
if ( atom->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom;
|
||||
outBuf.mBuf_Body = weeBook->mWeeBookAtom_Body;
|
||||
outBuf.mBuf_Fill = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) atom;
|
||||
outBuf.mBuf_Body = bigBook->mBigBookAtom_Body;
|
||||
outBuf.mBuf_Fill = bigBook->mBigBookAtom_Size;
|
||||
}
|
||||
else if ( atom->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom;
|
||||
outBuf.mBuf_Body = weeAnon->mWeeAnonAtom_Body;
|
||||
outBuf.mBuf_Fill = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom;
|
||||
outBuf.mBuf_Body = bigAnon->mBigAnonAtom_Body;
|
||||
outBuf.mBuf_Fill = bigAnon->mBigAnonAtom_Size;
|
||||
}
|
||||
else
|
||||
atom = 0; // show desire to put empty content in yarn
|
||||
}
|
||||
|
||||
if ( !atom ) // empty content for yarn?
|
||||
{
|
||||
outBuf.mBuf_Body = 0;
|
||||
outBuf.mBuf_Fill = 0;
|
||||
}
|
||||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkAtom::AliasYarn(mdbYarn* outYarn) const
|
||||
{
|
||||
outYarn->mYarn_More = 0;
|
||||
outYarn->mYarn_Form = 0;
|
||||
const morkAtom* atom = this;
|
||||
|
||||
if ( atom )
|
||||
{
|
||||
if ( atom->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom;
|
||||
outYarn->mYarn_Buf = weeBook->mWeeBookAtom_Body;
|
||||
outYarn->mYarn_Fill = weeBook->mAtom_Size;
|
||||
outYarn->mYarn_Size = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) atom;
|
||||
outYarn->mYarn_Buf = bigBook->mBigBookAtom_Body;
|
||||
outYarn->mYarn_Fill = bigBook->mBigBookAtom_Size;
|
||||
outYarn->mYarn_Size = bigBook->mBigBookAtom_Size;
|
||||
outYarn->mYarn_Form = bigBook->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( atom->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom;
|
||||
outYarn->mYarn_Buf = weeAnon->mWeeAnonAtom_Body;
|
||||
outYarn->mYarn_Fill = weeAnon->mAtom_Size;
|
||||
outYarn->mYarn_Size = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom;
|
||||
outYarn->mYarn_Buf = bigAnon->mBigAnonAtom_Body;
|
||||
outYarn->mYarn_Fill = bigAnon->mBigAnonAtom_Size;
|
||||
outYarn->mYarn_Size = bigAnon->mBigAnonAtom_Size;
|
||||
outYarn->mYarn_Form = bigAnon->mBigAnonAtom_Form;
|
||||
}
|
||||
else
|
||||
atom = 0; // show desire to put empty content in yarn
|
||||
}
|
||||
|
||||
if ( !atom ) // empty content for yarn?
|
||||
{
|
||||
outYarn->mYarn_Buf = 0;
|
||||
outYarn->mYarn_Fill = 0;
|
||||
outYarn->mYarn_Size = 0;
|
||||
// outYarn->mYarn_Grow = 0; // please don't modify the Grow slot
|
||||
}
|
||||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
mork_aid
|
||||
morkAtom::GetBookAtomAid() const // zero or book atom's ID
|
||||
{
|
||||
return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0;
|
||||
}
|
||||
|
||||
mork_scope
|
||||
morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope
|
||||
{
|
||||
mork_scope outScope = 0;
|
||||
if ( this->IsBook() )
|
||||
{
|
||||
const morkBookAtom* bookAtom = (const morkBookAtom*) this;
|
||||
morkAtomSpace* space = bookAtom->mBookAtom_Space;
|
||||
if ( space->IsAtomSpace() )
|
||||
outScope = space->SpaceScope();
|
||||
else
|
||||
space->NonAtomSpaceTypeError(ev);
|
||||
}
|
||||
|
||||
return outScope;
|
||||
}
|
||||
|
||||
void
|
||||
morkAtom::MakeCellUseForever(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = morkAtom_kForeverCellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
|
||||
++mAtom_CellUses;
|
||||
|
||||
return mAtom_CellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::CutCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mAtom_CellUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not frozen at max?
|
||||
--mAtom_CellUses;
|
||||
}
|
||||
else
|
||||
this->CellUsesUnderflowWarning(ev);
|
||||
|
||||
return mAtom_CellUses;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::CellUsesUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("mAtom_CellUses underflow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::BadAtomKindError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("bad mAtom_Kind");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::ZeroAidError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("zero atom ID");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::AtomSizeOverflowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("atom mAtom_Size overflow");
|
||||
}
|
||||
|
||||
void
|
||||
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindRowOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mOidAtom_Oid = inOid; // bitwise copy
|
||||
}
|
||||
|
||||
void
|
||||
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindTableOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mOidAtom_Oid = inOid; // bitwise copy
|
||||
}
|
||||
|
||||
void
|
||||
morkWeeAnonAtom::InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindWeeAnon;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mAtom_Size = (mork_u1) size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mWeeAnonAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mWeeAnonAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->AtomSizeOverflowError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigAnon;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mBigAnonAtom_Form = inForm;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mBigAnonAtom_Size = size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mBigAnonAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mBigAnonAtom_Body[ size ] = 0;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBookAtom::NonBookAtomTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkBookAtom");
|
||||
}
|
||||
|
||||
mork_u4
|
||||
morkBookAtom::HashFormAndBody(morkEnv* ev) const
|
||||
{
|
||||
// This hash is obviously a variation of the dragon book string hash.
|
||||
// (I won't bother to explain or rationalize this usage for you.)
|
||||
|
||||
register mork_u4 outHash = 0; // hash value returned
|
||||
register unsigned char c; // next character
|
||||
register const mork_u1* body; // body of bytes to hash
|
||||
mork_size size = 0; // the number of bytes to hash
|
||||
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
size = mAtom_Size;
|
||||
body = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
size = ((const morkBigBookAtom*) this)->mBigBookAtom_Size;
|
||||
body = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
|
||||
}
|
||||
else if ( this->IsFarBook() )
|
||||
{
|
||||
size = ((const morkFarBookAtom*) this)->mFarBookAtom_Size;
|
||||
body = ((const morkFarBookAtom*) this)->mFarBookAtom_Body;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NonBookAtomTypeError(ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const mork_u1* end = body + size;
|
||||
while ( body < end )
|
||||
{
|
||||
c = *body++;
|
||||
outHash <<= 4;
|
||||
outHash += c;
|
||||
mork_u4 top = outHash & 0xF0000000L; // top four bits
|
||||
if ( top ) // any of high four bits equal to one?
|
||||
{
|
||||
outHash ^= (top >> 24); // fold down high bits
|
||||
outHash ^= top; // zero top four bits
|
||||
}
|
||||
}
|
||||
|
||||
return outHash;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkBookAtom::EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const
|
||||
{
|
||||
mork_bool outEqual = morkBool_kFalse;
|
||||
|
||||
const mork_u1* body = 0; // body of inAtom bytes to compare
|
||||
mork_size size; // the number of inAtom bytes to compare
|
||||
mork_cscode form; // nominal charset for ioAtom
|
||||
|
||||
if ( inAtom->IsWeeBook() )
|
||||
{
|
||||
size = inAtom->mAtom_Size;
|
||||
body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
form = 0;
|
||||
}
|
||||
else if ( inAtom->IsBigBook() )
|
||||
{
|
||||
size = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Size;
|
||||
body = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Body;
|
||||
form = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( inAtom->IsFarBook() )
|
||||
{
|
||||
size = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Size;
|
||||
body = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Body;
|
||||
form = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Form;
|
||||
}
|
||||
else
|
||||
{
|
||||
inAtom->NonBookAtomTypeError(ev);
|
||||
return morkBool_kFalse;
|
||||
}
|
||||
|
||||
const mork_u1* thisBody = 0; // body of bytes in this to compare
|
||||
mork_size thisSize; // the number of bytes in this to compare
|
||||
mork_cscode thisForm; // nominal charset for this atom
|
||||
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
thisSize = mAtom_Size;
|
||||
thisBody = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body;
|
||||
thisForm = 0;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
thisSize = ((const morkBigBookAtom*) this)->mBigBookAtom_Size;
|
||||
thisBody = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
|
||||
thisForm = ((const morkBigBookAtom*) this)->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( this->IsFarBook() )
|
||||
{
|
||||
thisSize = ((const morkFarBookAtom*) this)->mFarBookAtom_Size;
|
||||
thisBody = ((const morkFarBookAtom*) this)->mFarBookAtom_Body;
|
||||
thisForm = ((const morkFarBookAtom*) this)->mFarBookAtom_Form;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NonBookAtomTypeError(ev);
|
||||
return morkBool_kFalse;
|
||||
}
|
||||
|
||||
// if atoms are empty, form is irrelevant
|
||||
if ( body && thisBody && size == thisSize && (!size || form == thisForm ))
|
||||
outEqual = (MORK_MEMCMP(body, thisBody, size) == 0);
|
||||
|
||||
return outEqual;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
morkBookAtom::CutBookAtomFromSpace(morkEnv* ev)
|
||||
{
|
||||
morkAtomSpace* space = mBookAtom_Space;
|
||||
if ( space )
|
||||
{
|
||||
mBookAtom_Space = 0;
|
||||
space->mAtomSpace_AtomBodies.CutAtom(ev, this);
|
||||
space->mAtomSpace_AtomAids.CutAtom(ev, this);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkWeeBookAtom::morkWeeBookAtom(mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = morkAtom_kKindWeeBook;
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
|
||||
mBookAtom_Space = 0;
|
||||
mBookAtom_Id = inAid;
|
||||
|
||||
mWeeBookAtom_Body[ 0 ] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkWeeBookAtom::InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( ioSpace )
|
||||
{
|
||||
if ( inAid )
|
||||
{
|
||||
if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindWeeBook;
|
||||
mBookAtom_Space = ioSpace;
|
||||
mBookAtom_Id = inAid;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mAtom_Size = (mork_u1) size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mWeeBookAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mWeeBookAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->AtomSizeOverflowError(ev);
|
||||
}
|
||||
else
|
||||
this->ZeroAidError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkBigBookAtom::InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( ioSpace )
|
||||
{
|
||||
if ( inAid )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigBook;
|
||||
mAtom_Size = 0;
|
||||
mBookAtom_Space = ioSpace;
|
||||
mBookAtom_Id = inAid;
|
||||
mBigBookAtom_Form = inForm;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mBigBookAtom_Size = size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mBigBookAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mBigBookAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->ZeroAidError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void morkFarBookAtom::InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( ioSpace )
|
||||
{
|
||||
if ( inAid )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindFarBook;
|
||||
mAtom_Size = 0;
|
||||
mBookAtom_Space = ioSpace;
|
||||
mBookAtom_Id = inAid;
|
||||
mFarBookAtom_Form = inForm;
|
||||
mFarBookAtom_Size = inBuf.mBuf_Fill;
|
||||
mFarBookAtom_Body = (mork_u1*) inBuf.mBuf_Body;
|
||||
}
|
||||
else
|
||||
this->ZeroAidError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
@ -1,398 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#define _MORKATOM_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkAtom_kMaxByteSize 255 /* max for 8-bit integer */
|
||||
#define morkAtom_kForeverCellUses 0x0FF /* max for 8-bit integer */
|
||||
#define morkAtom_kMaxCellUses 0x07F /* max for 7-bit integer */
|
||||
|
||||
#define morkAtom_kKindWeeAnon 'a' /* means morkWeeAnonAtom subclass */
|
||||
#define morkAtom_kKindBigAnon 'A' /* means morkBigAnonAtom subclass */
|
||||
#define morkAtom_kKindWeeBook 'b' /* means morkWeeBookAtom subclass */
|
||||
#define morkAtom_kKindBigBook 'B' /* means morkBigBookAtom subclass */
|
||||
#define morkAtom_kKindFarBook 'f' /* means morkFarBookAtom subclass */
|
||||
#define morkAtom_kKindRowOid 'r' /* means morkOidAtom subclass */
|
||||
#define morkAtom_kKindTableOid 't' /* means morkOidAtom subclass */
|
||||
|
||||
/*| Atom: .
|
||||
|*/
|
||||
class morkAtom { //
|
||||
|
||||
public:
|
||||
|
||||
mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
mork_change mAtom_Change; // how has this atom been changed?
|
||||
mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
morkAtom(mork_aid inAid, mork_u1 inKind);
|
||||
|
||||
mork_bool IsWeeAnon() const { return mAtom_Kind == morkAtom_kKindWeeAnon; }
|
||||
mork_bool IsBigAnon() const { return mAtom_Kind == morkAtom_kKindBigAnon; }
|
||||
mork_bool IsWeeBook() const { return mAtom_Kind == morkAtom_kKindWeeBook; }
|
||||
mork_bool IsBigBook() const { return mAtom_Kind == morkAtom_kKindBigBook; }
|
||||
mork_bool IsFarBook() const { return mAtom_Kind == morkAtom_kKindFarBook; }
|
||||
mork_bool IsRowOid() const { return mAtom_Kind == morkAtom_kKindRowOid; }
|
||||
mork_bool IsTableOid() const { return mAtom_Kind == morkAtom_kKindTableOid; }
|
||||
|
||||
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
|
||||
|
||||
public: // clean vs dirty
|
||||
|
||||
void SetAtomClean() { mAtom_Change = morkChange_kNil; }
|
||||
void SetAtomDirty() { mAtom_Change = morkChange_kAdd; }
|
||||
|
||||
mork_bool IsAtomClean() const { return mAtom_Change == morkChange_kNil; }
|
||||
mork_bool IsAtomDirty() const { return mAtom_Change == morkChange_kAdd; }
|
||||
|
||||
public: // atom space scope if IsBook() is true, or else zero:
|
||||
|
||||
mork_scope GetBookAtomSpaceScope(morkEnv* ev) const;
|
||||
// zero or book's space's scope
|
||||
|
||||
mork_aid GetBookAtomAid() const;
|
||||
// zero or book atom's ID
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkAtom() { }
|
||||
|
||||
public: // one-byte refcounting, freezing at maximum
|
||||
void MakeCellUseForever(morkEnv* ev);
|
||||
mork_u1 AddCellUse(morkEnv* ev);
|
||||
mork_u1 CutCellUse(morkEnv* ev);
|
||||
|
||||
mork_bool IsCellUseForever() const
|
||||
{ return mAtom_CellUses == morkAtom_kForeverCellUses; }
|
||||
|
||||
private: // warnings
|
||||
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // errors
|
||||
|
||||
static void BadAtomKindError(morkEnv* ev);
|
||||
static void ZeroAidError(morkEnv* ev);
|
||||
static void AtomSizeOverflowError(morkEnv* ev);
|
||||
|
||||
public: // yarns
|
||||
|
||||
mork_bool AsBuf(morkBuf& outBuf) const;
|
||||
mork_bool AliasYarn(mdbYarn* outYarn) const;
|
||||
mork_bool GetYarn(mdbYarn* outYarn) const;
|
||||
|
||||
private: // copying is not allowed
|
||||
morkAtom(const morkAtom& other);
|
||||
morkAtom& operator=(const morkAtom& other);
|
||||
};
|
||||
|
||||
/*| OidAtom: an atom that references a row or table by identity.
|
||||
|*/
|
||||
class morkOidAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
public:
|
||||
mdbOid mOidAtom_Oid; // identity of referenced object
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkOidAtom() { }
|
||||
void InitRowOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
void InitTableOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkOidAtom(const morkOidAtom& other);
|
||||
morkOidAtom& operator=(const morkOidAtom& other);
|
||||
};
|
||||
|
||||
/*| WeeAnonAtom: an atom whose content immediately follows morkAtom slots
|
||||
**| in an inline fashion, so that morkWeeAnonAtom contains both leading
|
||||
**| atom slots and then the content bytes without further overhead. Note
|
||||
**| that charset encoding is not indicated, so zero is implied for Latin1.
|
||||
**| (Non-Latin1 content must be stored in a morkBigAnonAtom with a charset.)
|
||||
**|
|
||||
**|| An anon (anonymous) atom has no identity, with no associated bookkeeping
|
||||
**| for lookup needed for sharing like a book atom.
|
||||
**|
|
||||
**|| A wee anon atom is immediate but not shared with any other users of this
|
||||
**| atom, so no bookkeeping for sharing is needed. This means the atom has
|
||||
**| no ID, because the atom has no identity other than this immediate content,
|
||||
**| and no hash table is needed to look up this particular atom. This also
|
||||
**| applies to the larger format morkBigAnonAtom, which has more slots.
|
||||
|*/
|
||||
class morkWeeAnonAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
mork_u1 mWeeAnonAtom_Body[ 1 ]; // 1st byte of immediate content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkWeeAnonAtom() { }
|
||||
void InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkWeeAnonAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkWeeAnonAtom(const morkWeeAnonAtom& other);
|
||||
morkWeeAnonAtom& operator=(const morkWeeAnonAtom& other);
|
||||
};
|
||||
|
||||
/*| BigAnonAtom: another immediate atom that cannot be encoded as the smaller
|
||||
**| morkWeeAnonAtom format because either the size is too great, and/or the
|
||||
**| charset is not the default zero for Latin1 and must be explicitly noted.
|
||||
**|
|
||||
**|| An anon (anonymous) atom has no identity, with no associated bookkeeping
|
||||
**| for lookup needed for sharing like a book atom.
|
||||
|*/
|
||||
class morkBigAnonAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
public:
|
||||
mork_cscode mBigAnonAtom_Form; // charset format encoding
|
||||
mork_size mBigAnonAtom_Size; // size of content vector
|
||||
mork_u1 mBigAnonAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBigAnonAtom() { }
|
||||
void InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf, mork_cscode inForm);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkBigAnonAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBigAnonAtom(const morkBigAnonAtom& other);
|
||||
morkBigAnonAtom& operator=(const morkBigAnonAtom& other);
|
||||
};
|
||||
|
||||
#define morkBookAtom_kMaxBodySize 1024 /* if larger, cannot be shared */
|
||||
|
||||
/*| BookAtom: the common subportion of wee book atoms and big book atoms that
|
||||
**| includes the atom ID and the pointer to the space referencing this atom
|
||||
**| through a hash table.
|
||||
|*/
|
||||
class morkBookAtom : public morkAtom { //
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is atom scope
|
||||
mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBookAtom() { }
|
||||
|
||||
static void NonBookAtomTypeError(morkEnv* ev);
|
||||
|
||||
public: // Hash() and Equal() for atom ID maps are same for all subclasses:
|
||||
|
||||
mork_u4 HashAid() const { return mBookAtom_Id; }
|
||||
mork_bool EqualAid(const morkBookAtom* inAtom) const
|
||||
{ return ( mBookAtom_Id == inAtom->mBookAtom_Id); }
|
||||
|
||||
public: // Hash() and Equal() for atom body maps know about subclasses:
|
||||
|
||||
// YOU CANNOT SUBCLASS morkBookAtom WITHOUT FIXING Hash and Equal METHODS:
|
||||
|
||||
mork_u4 HashFormAndBody(morkEnv* ev) const;
|
||||
mork_bool EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const;
|
||||
|
||||
public: // separation from containing space
|
||||
|
||||
void CutBookAtomFromSpace(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBookAtom(const morkBookAtom& other);
|
||||
morkBookAtom& operator=(const morkBookAtom& other);
|
||||
};
|
||||
|
||||
/*| FarBookAtom: this alternative format for book atoms was introduced
|
||||
**| in May 2000 in order to support finding atoms in hash tables without
|
||||
**| first copying the strings from original parsing buffers into a new
|
||||
**| atom format. This was consuming too much time. However, we can
|
||||
**| use morkFarBookAtom to stage a hash table query, as long as we then
|
||||
**| fix HashFormAndBody() and EqualFormAndBody() to use morkFarBookAtom
|
||||
**| correctly.
|
||||
**|
|
||||
**|| Note we do NOT intend that instances of morkFarBookAtom will ever
|
||||
**| be installed in hash tables, because this is not space efficient.
|
||||
**| We only expect to create temp instances for table lookups.
|
||||
|*/
|
||||
class morkFarBookAtom : public morkBookAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public:
|
||||
mork_cscode mFarBookAtom_Form; // charset format encoding
|
||||
mork_size mFarBookAtom_Size; // size of content vector
|
||||
mork_u1* mFarBookAtom_Body; // bytes are elsewere, out of line
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkFarBookAtom() { }
|
||||
void InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkFarBookAtom(const morkFarBookAtom& other);
|
||||
morkFarBookAtom& operator=(const morkFarBookAtom& other);
|
||||
};
|
||||
|
||||
/*| WeeBookAtom: .
|
||||
|*/
|
||||
class morkWeeBookAtom : public morkBookAtom { //
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public:
|
||||
mork_u1 mWeeBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkWeeBookAtom() { }
|
||||
morkWeeBookAtom(mork_aid inAid);
|
||||
|
||||
void InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkWeeBookAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkWeeBookAtom(const morkWeeBookAtom& other);
|
||||
morkWeeBookAtom& operator=(const morkWeeBookAtom& other);
|
||||
};
|
||||
|
||||
/*| BigBookAtom: .
|
||||
|*/
|
||||
class morkBigBookAtom : public morkBookAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public:
|
||||
mork_cscode mBigBookAtom_Form; // charset format encoding
|
||||
mork_size mBigBookAtom_Size; // size of content vector
|
||||
mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBigBookAtom() { }
|
||||
void InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkBigBookAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBigBookAtom(const morkBigBookAtom& other);
|
||||
morkBigBookAtom& operator=(const morkBigBookAtom& other);
|
||||
};
|
||||
|
||||
/*| MaxBookAtom: .
|
||||
|*/
|
||||
class morkMaxBookAtom : public morkBigBookAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
// mork_cscode mBigBookAtom_Form; // charset format encoding
|
||||
// mork_size mBigBookAtom_Size; // size of content vector
|
||||
// mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public:
|
||||
mork_u1 mMaxBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkMaxBookAtom() { }
|
||||
void InitMaxBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{ this->InitBigBookAtom(ev, inBuf, inForm, ioSpace, inAid); }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkMaxBookAtom(const morkMaxBookAtom& other);
|
||||
morkMaxBookAtom& operator=(const morkMaxBookAtom& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOM_ */
|
||||
|
|
@ -1,469 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomAidMap::CloseMorkNode(morkEnv* ev) // CloseAtomAidMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomAidMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
: morkProbeMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
ioSlotHeap, morkAtomAidMap_kStartSlotCount,
|
||||
/*inZeroIsClearKey*/ morkBool_kTrue)
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomAidMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomAidMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->CloseProbeMap(ev);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->CloseMap(ev);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
|
||||
/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b)
|
||||
morkAtomAidMap::MapTest(morkEnv* ev, const void* inMapKey,
|
||||
const void* inAppKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inMapKey;
|
||||
if ( key )
|
||||
{
|
||||
mork_bool hit = key->EqualAid(*(const morkBookAtom**) inAppKey);
|
||||
return ( hit ) ? morkTest_kHit : morkTest_kMiss;
|
||||
}
|
||||
else
|
||||
return morkTest_kVoid;
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b)
|
||||
morkAtomAidMap::MapHash(morkEnv* ev, const void* inAppKey) const
|
||||
{
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inAppKey;
|
||||
if ( key )
|
||||
return key->HashAid();
|
||||
else
|
||||
{
|
||||
ev->NilPointerWarning();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4
|
||||
morkAtomAidMap::ProbeMapHashMapKey(morkEnv* ev,
|
||||
const void* inMapKey) const
|
||||
{
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inMapKey;
|
||||
if ( key )
|
||||
return key->HashAid();
|
||||
else
|
||||
{
|
||||
ev->NilPointerWarning();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualAid(
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkBookAtom**) inKey)->HashAid();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->MapAtPut(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
MORK_USED_1(inAtom);
|
||||
morkProbeMap::ProbeMapCutError(ev);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->MapAt(ev, &inAtom, &key, /*val*/ (void*) 0);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid)
|
||||
{
|
||||
morkWeeBookAtom weeAtom(inAid);
|
||||
morkBookAtom* key = &weeAtom; // we need a pointer
|
||||
morkBookAtom* oldKey = 0; // old key in the map
|
||||
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->MapAt(ev, &key, &oldKey, /*val*/ (void*) 0);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomBodyMap::CloseMorkNode(morkEnv* ev) // CloseAtomBodyMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomBodyMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
: morkProbeMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
ioSlotHeap, morkAtomBodyMap_kStartSlotCount,
|
||||
/*inZeroIsClearKey*/ morkBool_kTrue)
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomBodyMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomBodyMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomBodyMap::CloseAtomBodyMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->CloseProbeMap(ev);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->CloseMap(ev);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
|
||||
/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b)
|
||||
morkAtomBodyMap::MapTest(morkEnv* ev, const void* inMapKey,
|
||||
const void* inAppKey) const
|
||||
{
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inMapKey;
|
||||
if ( key )
|
||||
{
|
||||
return ( key->EqualFormAndBody(ev, *(const morkBookAtom**) inAppKey) ) ?
|
||||
morkTest_kHit : morkTest_kMiss;
|
||||
}
|
||||
else
|
||||
return morkTest_kVoid;
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b)
|
||||
morkAtomBodyMap::MapHash(morkEnv* ev, const void* inAppKey) const
|
||||
{
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inAppKey;
|
||||
if ( key )
|
||||
return key->HashFormAndBody(ev);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4
|
||||
morkAtomBodyMap::ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const
|
||||
{
|
||||
const morkBookAtom* key = *(const morkBookAtom**) inMapKey;
|
||||
if ( key )
|
||||
return key->HashFormAndBody(ev);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualFormAndBody(ev,
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKey)->HashFormAndBody(ev);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->MapAtPut(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
MORK_USED_1(inAtom);
|
||||
morkProbeMap::ProbeMapCutError(ev);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
#ifdef MORK_ENABLE_PROBE_MAPS
|
||||
this->MapAt(ev, &inAtom, &key, /*val*/ (void*) 0);
|
||||
#else /*MORK_ENABLE_PROBE_MAPS*/
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
#endif /*MORK_ENABLE_PROBE_MAPS*/
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkAtomRowMap::~morkAtomRowMap()
|
||||
{
|
||||
}
|
||||
|
||||
// I changed to sizeof(mork_ip) from sizeof(mork_aid) to fix a crash on
|
||||
// 64 bit machines. I am not sure it was the right way to fix the problem,
|
||||
// but it does stop the crash. Perhaps we should be using the
|
||||
// morkPointerMap instead?
|
||||
morkAtomRowMap::morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn)
|
||||
: morkIntMap(ev, inUsage, sizeof(mork_ip), ioHeap, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
, mAtomRowMap_IndexColumn( inIndexColumn )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomRowMap;
|
||||
}
|
||||
|
||||
void morkAtomRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||
// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
{
|
||||
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
|
||||
if ( aid )
|
||||
this->AddAid(ev, aid, ioRow);
|
||||
}
|
||||
|
||||
void morkAtomRowMap::CutRow(morkEnv* ev, morkRow* ioRow)
|
||||
// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
{
|
||||
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
|
||||
if ( aid )
|
||||
this->CutAid(ev, aid);
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|