merge the last green changeset on m-c to fx-team

This commit is contained in:
Tim Taubert 2011-08-09 18:00:52 +02:00
Родитель 342a2e3b0d 719f847b93
Коммит 2d6ac469f9
750 изменённых файлов: 13785 добавлений и 49138 удалений

Просмотреть файл

@ -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

Двоичные данные
browser/themes/pinstripe/browser/Toolbar-lion.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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

Двоичные данные
browser/themes/pinstripe/browser/keyhole-circle-lion.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичные данные
browser/themes/pinstripe/browser/keyhole-circle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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@

Просмотреть файл

@ -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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше