Merge mozilla-central, including the Electrolysis changes, into the branch for bug 568691.

This commit is contained in:
Benjamin Smedberg 2010-07-01 11:55:57 -04:00
commit a677e5bf91
435 changed files with 29427 additions and 5558 deletions

11
.hgtags
View File

@ -35,6 +35,17 @@ fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
941ad9d7d079246481f365c3cfbfc75a5bbefc94 last-mozilla-central
2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
925595f3c08634cc42e33158ea6858bb55623ef7 last-mozilla-central
dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R9
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R10
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11

View File

@ -56,7 +56,7 @@ interface nsIDOMDOMStringList;
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(420f0f49-27c1-4ac1-b509-5aba4353909b)]
[scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
interface nsIAccessibleRetrieval : nsISupports
{
/**
@ -73,30 +73,6 @@ interface nsIAccessibleRetrieval : nsISupports
*/
nsIAccessible getAccessibleFor(in nsIDOMNode aNode);
/**
* The same like getAccessibleFor method except it returns accessible only if
* it is attached, i.e. accessible is certified to be a descendent of the root
* accessible.
*
* @param aNode - the DOM node to get an accessible for.
*
* @return - the accessible for the given DOM node.
*/
nsIAccessible getAttachedAccessibleFor(in nsIDOMNode aNode);
/**
* Return an DOM node that is relevant to attached accesible check. This
* node is either from bindings chain if given node is anonymous and owner
* binding denies accessible in anonymous content or given node (it's not
* important whether it is accessible or not). This method doesn't create
* accessible object for returned node.
*
* @param aNode - the DOM node to get relevant content node.
*
* @return - the DOM node for parent attached accessible
*/
nsIDOMNode getRelevantContentNodeFor(in nsIDOMNode aNode);
/**
* Returns accessible role as a string.
*

View File

@ -113,8 +113,8 @@ nsAccTreeWalker::GetNextChildInternal(PRBool aNoWalkUp)
PRBool isHidden = PR_FALSE;
nsRefPtr<nsAccessible> accessible =
GetAccService()->GetAccessible(childNode, presShell, mWeakShell,
&isHidden);
GetAccService()->GetOrCreateAccessible(childNode, presShell, mWeakShell,
&isHidden);
if (accessible)
return accessible.forget();

View File

@ -527,31 +527,28 @@ nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
nsCOMPtr<nsINode> resultNode =
nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(resultNode));
// Get text accessible containing the result node.
while (resultNode) {
// Make sure to get the correct starting node for selection events inside
// XBL content trees.
resultNode = GetAccService()->GetRelevantContentNodeFor(resultNode);
if (!resultNode->IsNodeOfType(nsINode::eTEXT)) {
nsAccessible *accessible = GetAccService()->GetAccessible(resultNode);
if (accessible) {
nsHyperTextAccessible *textAcc = nsnull;
CallQueryInterface(accessible, &textAcc);
if (textAcc) {
if (aNode)
NS_ADDREF(*aNode = resultNode);
return textAcc;
}
}
}
resultNode = resultNode->GetNodeParent();
nsAccessible* accessible =
GetAccService()->GetAccessibleOrContainer(resultNode, weakShell);
if (!accessible) {
NS_NOTREACHED("No nsIAccessibleText for selection change event!");
return nsnull;
}
NS_NOTREACHED("No nsIAccessibleText for selection change event!");
do {
nsHyperTextAccessible* textAcc = nsnull;
CallQueryInterface(accessible, &textAcc);
if (textAcc) {
if (aNode)
NS_ADDREF(*aNode = accessible->GetNode());
return textAcc;
}
} while (accessible = accessible->GetParent());
NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!");
return nsnull;
}
@ -634,7 +631,8 @@ nsIntPoint
nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode)
{
nsAccessible *parent =
GetAccService()->GetContainerAccessible(aAccessNode->GetNode(), PR_TRUE);
GetAccService()->GetContainerAccessible(aAccessNode->GetNode(),
aAccessNode->GetWeakShell());
if (!parent)
return nsIntPoint(0, 0);
@ -815,12 +813,6 @@ nsAccUtils::MustPrune(nsIAccessible *aAccessible)
role == nsIAccessibleRole::ROLE_SEPARATOR;
}
PRBool
nsAccUtils::IsNodeRelevant(nsINode *aNode)
{
return aNode == GetAccService()->GetRelevantContentNodeFor(aNode);
}
nsresult
nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
nsIAccessibleTableCell *aCell,

View File

@ -410,12 +410,6 @@ public:
*/
static PRBool MustPrune(nsIAccessible *aAccessible);
/**
* Return true if the given node can be accessible and attached to
* the document's accessible tree.
*/
static PRBool IsNodeRelevant(nsINode *aNode);
/**
* Search hint enum constants. Used by GetHeaderCellsFor() method.
*/

View File

@ -176,6 +176,11 @@ public:
*/
already_AddRefed<nsIPresShell> GetPresShell();
/**
* Return presentation shell for the accessible.
*/
nsIWeakReference* GetWeakShell() const { return mWeakShell; }
protected:
nsPresContext* GetPresContext();

View File

@ -148,30 +148,18 @@ nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
if (!document)
return;
nsINode *targetNode = aTarget;
nsAccessible *targetAcc = GetAccessible(targetNode);
// Getting the targetAcc above will have ensured accessible doc creation.
// XXX Bug 561683
nsDocAccessible *docAccessible = GetDocAccessible(document);
if (!docAccessible)
return;
// If the jump target is not accessible then fire an event for nearest
// accessible in parent chain.
if (!targetAcc) {
targetAcc = GetContainerAccessible(targetNode, PR_TRUE);
targetNode = targetAcc->GetNode();
}
NS_ASSERTION(targetNode,
"No accessible in parent chain!? Expect at least a document accessible.");
if (!targetNode)
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aTarget));
nsAccessible* targetAcc = GetAccessibleOrContainer(aTarget, weakShell);
if (!targetAcc)
return;
nsINode* targetNode = targetAcc->GetNode();
// XXX note in rare cases the node could go away before we flush the queue,
// for example if the node becomes inaccessible, or is removed from the DOM.
docAccessible->
GetDocAccessible(document)->
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
targetNode);
}
@ -513,31 +501,6 @@ nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aDOMNode,
nsIAccessible **aAccessible)
{
NS_ENSURE_ARG(aDOMNode);
NS_ENSURE_ARG_POINTER(aAccessible);
nsCOMPtr<nsINode> node(do_QueryInterface(aDOMNode));
NS_IF_ADDREF(*aAccessible = GetAttachedAccessibleFor(node));
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
nsIDOMNode **aRelevantNode)
{
NS_ENSURE_ARG(aNode);
NS_ENSURE_ARG_POINTER(aRelevantNode);
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
nsINode *relevantNode = GetRelevantContentNodeFor(node);
CallQueryInterface(relevantNode, aRelevantNode);
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
{
@ -730,46 +693,25 @@ nsAccessibilityService::GetAccessibleInShell(nsINode* aNode,
return nsnull;
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
nsRefPtr<nsAccessible> accessible =
GetAccessible(aNode, aPresShell, weakShell);
return accessible;
return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessibilityService public
nsAccessible *
nsAccessibilityService::GetAccessible(nsINode *aNode)
nsAccessible*
nsAccessibilityService::GetAccessible(nsINode* aNode)
{
if (!aNode)
return nsnull;
nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
if (!presShell)
return nsnull;
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
weakShell);
return accessible;
if (aNode) {
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aNode));
if (weakShell)
return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
}
return nsnull;
}
nsAccessible *
nsAccessibilityService::GetAccessibleInWeakShell(nsINode *aNode,
nsIWeakReference *aWeakShell)
{
if (!aNode || !aWeakShell)
return nsnull;
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
aWeakShell);
return accessible;
}
nsAccessible *
nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
PRBool aCanCreate)
nsAccessible*
nsAccessibilityService::GetCachedContainerAccessible(nsINode* aNode)
{
if (!aNode)
return nsnull;
@ -786,32 +728,12 @@ nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
nsAccessible *accessible = nsnull;
while (!accessible && (currNode = currNode->GetNodeParent())) {
currNode = GetAccService()->GetRelevantContentNodeFor(currNode);
if (aCanCreate) {
accessible = GetAccService()->GetAccessibleInWeakShell(currNode,
weakShell);
} else {
// Only return cached accessible, don't create anything.
accessible = GetCachedAccessible(currNode, weakShell);
}
}
while ((currNode = currNode->GetNodeParent()) &&
!(accessible = GetCachedAccessible(currNode, weakShell)));
return accessible;
}
nsAccessible *
nsAccessibilityService::GetAttachedAccessibleFor(nsINode *aNode)
{
nsINode *relevantNode = GetRelevantContentNodeFor(aNode);
if (relevantNode != aNode)
return nsnull;
return GetAccessible(relevantNode);
}
PRBool
nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
nsRoleMapEntry *aRoleMapEntry)
@ -863,10 +785,10 @@ static PRBool HasRelatedContent(nsIContent *aContent)
}
already_AddRefed<nsAccessible>
nsAccessibilityService::GetAccessible(nsINode *aNode,
nsIPresShell *aPresShell,
nsIWeakReference *aWeakShell,
PRBool *aIsHidden)
nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
nsIPresShell* aPresShell,
nsIWeakReference* aWeakShell,
PRBool* aIsHidden)
{
if (!aPresShell || !aWeakShell || !aNode || gIsShutdown)
return nsnull;
@ -1244,71 +1166,73 @@ nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant);
}
nsINode *
nsAccessibilityService::GetRelevantContentNodeFor(nsINode *aNode)
nsAccessible*
nsAccessibilityService::GetAccessibleByRule(nsINode* aNode,
nsIWeakReference* aWeakShell,
EWhatAccToGet aWhatToGet)
{
// The method returns node that is relevant for attached accessible check.
// Sometimes element that is XBL widget hasn't accessible children in
// anonymous content. This method check whether given node can be accessible
// by looking through all nested bindings that given node is anonymous for. If
// there is XBL widget that deniedes to be accessible for given node then the
// method returns that XBL widget otherwise it returns given node.
// For example, the algorithm allows us to handle following cases:
// 1. xul:dialog element has buttons (like 'ok' and 'cancel') in anonymous
// content. When node is dialog's button then we dialog's button since button
// of xul:dialog is accessible anonymous node.
// 2. xul:texbox has html:input in anonymous content. When given node is
// html:input elmement then we return xul:textbox since xul:textbox doesn't
// allow accessible nodes in anonymous content.
// 3. xforms:input that is hosted in xul document contains xul:textbox
// element. When given node is html:input or xul:textbox then we return
// xforms:input element since xforms:input hasn't accessible anonymous
// children.
if (!aNode)
if (!aNode || !aWeakShell)
return nsnull;
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (content) {
// Build stack of binding parents so we can walk it in reverse.
nsIContent *bindingParent;
nsCOMArray<nsIContent> bindingsStack;
nsAccessible* cachedAcc = GetCachedAccessible(aNode, aWeakShell);
if (cachedAcc) {
if (aWhatToGet & eGetAccForNode)
return cachedAcc;
for (bindingParent = content->GetBindingParent(); bindingParent != nsnull &&
bindingParent != bindingParent->GetBindingParent();
bindingParent = bindingParent->GetBindingParent()) {
bindingsStack.AppendObject(bindingParent);
}
// XXX: while nsAccessible::GetParent() tries to repair broken tree and
// may not return cached parent then we use GetAccessibleOrContainer().
return GetAccessibleByRule(aNode->GetNodeParent(), aWeakShell,
eGetAccForNodeOrContainer);
}
PRInt32 bindingsCount = bindingsStack.Count();
for (PRInt32 index = bindingsCount - 1; index >= 0 ; index--) {
bindingParent = bindingsStack[index];
// Go up looking for the nearest accessible container stored in cache.
nsTArray<nsINode*> nodes;
nsINode* node = aNode;
while ((node = node->GetNodeParent()) &&
!(cachedAcc = GetCachedAccessible(node, aWeakShell)))
nodes.AppendElement(node);
// Try to get an accessible by type since XBL widget can be accessible
// only if it implements nsIAccessibleProvider interface.
nsCOMPtr<nsIWeakReference> weakShell =
nsCoreUtils::GetWeakShellFor(bindingParent);
// Node is not in accessible document.
if (!cachedAcc)
return nsnull;
// XXX: it's a hack we should try the cache before, otherwise to cache
// the accessible.
nsRefPtr<nsAccessible> accessible =
CreateAccessibleByType(bindingParent, weakShell);
if (accessible) {
if (!accessible->GetAllowsAnonChildAccessibles())
return bindingParent;
// If children of the cached accessible weren't initialized then go down to
// the given node and create accessible tree.
nsAccessible* containerAcc = cachedAcc;
if (!cachedAcc->AreChildrenCached()) {
cachedAcc->EnsureChildren();
for (PRInt32 idx = nodes.Length() - 1; idx >= 0; idx--) {
cachedAcc = GetCachedAccessible(nodes[idx], aWeakShell);
if (cachedAcc) {
cachedAcc->EnsureChildren();
containerAcc = cachedAcc;
}
}
}
return aNode;
// If the given node is accessible then it should be cached at this point.
// Exception is an area element because area and imagemap nodes aren't in
// the same parent chain.
cachedAcc = GetCachedAccessible(aNode, aWeakShell);
if (!cachedAcc && aNode->IsElement()) {
nsIFrame* frame = aNode->AsElement()->GetPrimaryFrame();
if (frame && frame->GetContent() != aNode)
cachedAcc = GetAreaAccessible(frame, aNode, aWeakShell, &containerAcc);
}
if ((aWhatToGet & eGetAccForNode) && cachedAcc)
return cachedAcc;
else if (aWhatToGet & eGetAccForContainer)
return containerAcc;
return nsnull;
}
nsAccessible*
nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
nsINode *aAreaNode,
nsIWeakReference *aWeakShell)
nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame,
nsINode* aAreaNode,
nsIWeakReference* aWeakShell,
nsAccessible** aImageAccessible)
{
// Check if frame is an image frame, and content is <area>.
nsIImageFrame *imageFrame = do_QueryFrame(aImageFrame);
@ -1331,6 +1255,9 @@ nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
return nsnull;
}
if (aImageAccessible)
*aImageAccessible = imageAcc;
// Make sure <area> accessible children of the image map are cached so
// that they should be available in global cache.
imageAcc->EnsureChildren();

View File

@ -127,7 +127,8 @@ public:
static PRBool IsShutdown() { return gIsShutdown; }
/**
* Return an accessible for the given DOM node.
* Return an accessible for the given DOM node from the cache or create new
* one.
*
* @param aNode [in] the given node
* @param aPresShell [in] the pres shell of the node
@ -136,57 +137,52 @@ public:
* hidden
*/
already_AddRefed<nsAccessible>
GetAccessible(nsINode *aNode, nsIPresShell *aPresShell,
nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
GetOrCreateAccessible(nsINode* aNode, nsIPresShell* aPresShell,
nsIWeakReference* aWeakShell,
PRBool* aIsHidden = nsnull);
/**
* Return an accessible for the given DOM node.
*/
nsAccessible *GetAccessible(nsINode *aNode);
nsAccessible* GetAccessible(nsINode* aNode);
/**
* Return an accessible for a DOM node in the given pres shell.
*
* @param aNode [in] the given node.
* @param aPresShell [in] the presentation shell of the given node.
* Return an accessible for a DOM node in the given presshell.
*
* @param aNode [in] the given node
* @param aWeakShell [in] the presentation shell for the given node
*/
nsAccessible *GetAccessibleInWeakShell(nsINode *aNode,
nsIWeakReference *aPresShell);
inline nsAccessible* GetAccessibleInWeakShell(nsINode* aNode,
nsIWeakReference* aWeakShell)
{
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNode);
}
/**
* Return the first accessible parent of a DOM node.
* Return an accessible for the given DOM node or container accessible if
* the node is not accessible.
*/
inline nsAccessible* GetAccessibleOrContainer(nsINode* aNode,
nsIWeakReference* aWeakShell)
{
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNodeOrContainer);
}
/**
* Return a container accessible for the given DOM node.
*/
inline nsAccessible* GetContainerAccessible(nsINode* aNode,
nsIWeakReference* aWeakShell)
{
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForContainer);
}
/**
* Return the first cached accessible parent of a DOM node.
*
* @param aDOMNode [in] the DOM node to get an accessible for
* @param aCanCreate [in] specifies if accessible can be created if it didn't
* exist
*/
nsAccessible *GetContainerAccessible(nsINode *aNode, PRBool aCanCreate);
/**
* The same as getAccessibleFor method except it returns accessible only if
* it is attached, i.e. accessible is certified to be a descendant of the root
* accessible.
*
* XXX: this method must go away once we'll implement correct accessible tree.
*
* @param aNode [in] the DOM node to get an accessible for
* @return the accessible for the given DOM node
*/
nsAccessible *GetAttachedAccessibleFor(nsINode *aNode);
/**
* Return an DOM node that is relevant to attached accessible check. This
* node is either from bindings chain if given node is anonymous and owner
* binding denies accessible in anonymous content or given node (it's not
* important whether it is accessible or not). This method doesn't create
* accessible object for returned node.
*
* XXX: this method must go away once we'll implement correct accessible tree.
*
* @param aNode [in] the DOM node to get relevant content node
* @return the DOM node for parent attached accessible
*/
nsINode *GetRelevantContentNodeFor(nsINode *aNode);
nsAccessible* GetCachedContainerAccessible(nsINode *aNode);
/**
* Initialize an accessible and cache it. The method should be called for
@ -231,11 +227,30 @@ private:
*/
void Shutdown();
enum EWhatAccToGet {
eGetAccForNode = 0x1,
eGetAccForContainer = 0x2,
eGetAccForNodeOrContainer = eGetAccForNode | eGetAccForContainer
};
/**
* Return accessible or accessible container for the given node in presshell.
*/
nsAccessible* GetAccessibleByRule(nsINode* aNode,
nsIWeakReference* aWeakShell,
EWhatAccToGet aWhatToGet);
/**
* Return accessible for HTML area element associated with an image map.
*
* @param aImageFrame [in] image frame
* @param aAreaNode [in] area node
* @param aWeakShell [in] presshell of image frame
* @param aImageAccessible [out, optional] image accessible, isn't addrefed
*/
nsAccessible* GetAreaAccessible(nsIFrame* aImageFrame, nsINode* aAreaNode,
nsIWeakReference* aWeakShell);
nsIWeakReference* aWeakShell,
nsAccessible** aImageAccessible = nsnull);
/**
* Create accessible for the element implementing nsIAccessibleProvider

View File

@ -813,16 +813,13 @@ nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild,
return NS_OK;
}
nsINode *relevantNode = GetAccService()->GetRelevantContentNodeFor(content);
nsAccessible *accessible = GetAccService()->GetAccessible(relevantNode);
// Get accessible for the node with the point or the first accessible in
// the DOM parent chain.
nsAccessible* accessible =
GetAccService()->GetAccessibleOrContainer(content, mWeakShell);
if (!accessible) {
// No accessible for the node with the point, so find the first
// accessible in the DOM parent chain
accessible = GetAccService()->GetContainerAccessible(relevantNode, PR_TRUE);
if (!accessible) {
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
if (accessible == this) {
@ -1242,8 +1239,6 @@ nsresult
nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
{
NS_ENSURE_ARG_POINTER(aEvent);
NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(aEvent->GetNode()),
NS_ERROR_FAILURE);
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();
@ -2675,22 +2670,7 @@ nsAccessible::Init()
void *uniqueID = nsnull;
GetUniqueID(&uniqueID);
if (!docAcc->CacheAccessible(uniqueID, this))
return PR_FALSE;
// Make sure an ancestor in real content is cached so that
// nsDocAccessible::RefreshNodes() can find the anonymous subtree to release
// when the root node goes away. /Specific examples of where this is used:
// <input type="file"> and <xul:findbar>.
// XXX: remove this once we create correct accessible tree.
if (mContent && mContent->IsInAnonymousSubtree()) {
nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
PR_TRUE);
if (parent)
parent->EnsureChildren();
}
return PR_TRUE;
return docAcc->CacheAccessible(uniqueID, this);
}
void
@ -2779,31 +2759,33 @@ nsAccessible::InvalidateChildren()
nsAccessible*
nsAccessible::GetParent()
{
if (mParent)
return mParent;
if (IsDefunct())
return nsnull;
if (mParent)
return mParent;
// XXX: mParent can be null randomly because supposedly we get layout
// notification and invalidate parent-child relations, this accessible stays
// unattached. This should gone after bug 572951. Other reason is bug 574588
// since CacheChildren() implementation calls nsAccessible::GetRole() what
// can need to get a parent and we are here as result.
NS_WARNING("Bad accessible tree!");
#ifdef DEBUG
nsDocAccessible *docAccessible = GetDocAccessible();
NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
#endif
nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
PR_TRUE);
nsAccessible* parent = GetAccService()->GetContainerAccessible(mContent,
mWeakShell);
NS_ASSERTION(parent, "No accessible parent for valid accessible!");
if (!parent)
return nsnull;
#ifdef DEBUG
NS_ASSERTION(!parent->IsDefunct(), "Defunct parent!");
// Repair parent-child relations.
parent->EnsureChildren();
if (parent != mParent)
NS_WARNING("Bad accessible tree!");
#endif
NS_ASSERTION(parent == mParent, "Wrong children repair!");
return parent;
}
@ -2845,25 +2827,6 @@ nsAccessible::GetIndexInParent()
return parent ? parent->GetIndexOf(this) : -1;
}
nsAccessible*
nsAccessible::GetCachedParent()
{
if (IsDefunct())
return nsnull;
return mParent;
}
nsAccessible*
nsAccessible::GetCachedFirstChild()
{
if (IsDefunct())
return nsnull;
return mChildren.SafeElementAt(0, nsnull);
}
#ifdef DEBUG
PRBool
nsAccessible::IsInCache()

View File

@ -235,7 +235,7 @@ public:
/**
* Return parent accessible.
*/
virtual nsAccessible* GetParent();
nsAccessible* GetParent();
/**
* Return child accessible at the given index.
@ -263,14 +263,13 @@ public:
PRBool HasChildren() { return !!GetChildAt(0); }
/**
* Return parent accessible only if cached.
* Return cached accessible of parent-child relatives.
*/
nsAccessible* GetCachedParent();
nsAccessible* GetCachedParent() const { return mParent; }
nsAccessible* GetCachedFirstChild() const
{ return mChildren.SafeElementAt(0, nsnull); }
/**
* Return first child accessible only if cached.
*/
nsAccessible* GetCachedFirstChild();
PRBool AreChildrenCached() const { return mAreChildrenInitialized; }
#ifdef DEBUG
/**

View File

@ -405,12 +405,6 @@ nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
return NS_OK;
}
nsAccessible*
nsApplicationAccessible::GetParent()
{
return nsnull;
}
void
nsApplicationAccessible::InvalidateChildren()
{

View File

@ -113,7 +113,6 @@ public:
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsAccessible* GetParent();
virtual void InvalidateChildren();
virtual PRBool AppendChild(nsAccessible* aChild);

View File

@ -955,8 +955,6 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
}
NS_ASSERTION(aContent, "No node for attr modified");
if (!aContent || !nsAccUtils::IsNodeRelevant(aContent))
return;
// Universal boolean properties that don't require a role. Fire the state
// change when disabled or aria-disabled attribute is set.
@ -1272,12 +1270,6 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsAccessible*
nsDocAccessible::GetParent()
{
return IsDefunct() ? nsnull : mParent.get();
}
#ifdef DEBUG_ACCDOCMGR
nsresult
nsDocAccessible::HandleAccEvent(nsAccEvent *aAccEvent)
@ -1513,17 +1505,18 @@ nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
nsAccessible *containerAccessible = nsnull;
if (accessible)
nsAccessible* containerAccessible = nsnull;
if (accessible) {
containerAccessible = accessible->GetParent();
if (!containerAccessible) {
} else {
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(node));
containerAccessible = GetAccService()->GetContainerAccessible(node,
PR_TRUE);
if (!containerAccessible)
containerAccessible = this;
weakShell);
}
if (!containerAccessible)
containerAccessible = this;
if (isAsync) {
// For asynch show, delayed invalidatation of parent's children
containerAccessible->InvalidateChildren();
@ -1769,7 +1762,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// Just invalidate accessible hierarchy and return,
// otherwise the page load time slows down way too much
nsAccessible *containerAccessible =
GetAccService()->GetContainerAccessible(childNode, PR_FALSE);
GetAccService()->GetCachedContainerAccessible(childNode);
if (!containerAccessible) {
containerAccessible = this;
}
@ -1805,7 +1798,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
#endif
nsAccessible *containerAccessible =
GetAccService()->GetContainerAccessible(childNode, PR_TRUE);
GetAccService()->GetCachedContainerAccessible(childNode);
if (!containerAccessible) {
containerAccessible = this;
}
@ -1950,7 +1943,7 @@ nsDocAccessible::FireShowHideEvents(nsINode *aNode,
accessible = GetCachedAccessible(aNode);
} else {
// Allow creation of new accessibles for show events
accessible = GetAccService()->GetAttachedAccessibleFor(aNode);
accessible = GetAccService()->GetAccessible(aNode);
}
}

View File

@ -113,7 +113,6 @@ public:
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
virtual nsAccessible* GetParent();
#ifdef DEBUG_ACCDOCMGR
virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);

View File

@ -458,37 +458,24 @@ nsRootAccessible::FireCurrentFocusEvent()
if (IsDefunct())
return;
// Simulate a focus event so that we can reuse code that fires focus for
// container children like treeitems.
nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
if (!focusedNode) {
return; // No current focus
}
// Simulate a focus event so that we can reuse code that fires focus for container children like treeitems
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
if (docEvent) {
nsCOMPtr<nsIDOMEvent> event;
if (NS_SUCCEEDED(docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
getter_AddRefs(event))) &&
NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
// Get the target node we really want for the event.
nsINode *targetNode =
GetAccService()->GetRelevantContentNodeFor(focusedNode);
if (targetNode) {
// If the focused element is document element or HTML body element
// then simulate the focus event for the document.
nsINode *document = targetNode->GetOwnerDoc();
if (targetNode == nsCoreUtils::GetRoleContent(document)) {
HandleEventWithTarget(event, document);
return;
}
// Otherwise simulate the focus event for currently focused node.
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
privateEvent->SetTarget(target);
HandleEventWithTarget(event, targetNode);
}
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
privateEvent->SetTarget(target);
HandleEvent(event);
}
}
}
@ -496,61 +483,42 @@ nsRootAccessible::FireCurrentFocusEvent()
////////////////////////////////////////////////////////////////////////////////
// nsIDOMEventListener
NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
NS_IMETHODIMP
nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
{
// Turn DOM events in accessibility events
// Get info about event and target
nsCOMPtr<nsIDOMNode> targetNode;
GetTargetNode(aEvent, getter_AddRefs(targetNode));
if (!targetNode)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
NS_ENSURE_STATE(nsevent);
nsCOMPtr<nsINode> node(do_QueryInterface(targetNode));
return HandleEventWithTarget(aEvent, node);
}
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
nsCOMPtr<nsINode> origTarget(do_QueryInterface(domEventTarget));
NS_ENSURE_STATE(origTarget);
// nsRootAccessible protected member
nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
nsINode* aTargetNode)
{
nsAutoString eventType;
aEvent->GetType(eventType);
nsAutoString localName;
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(aTargetNode));
if (targetContent)
targetContent->NodeInfo()->GetName(localName);
#ifdef MOZ_XUL
PRBool isTree = localName.EqualsLiteral("tree");
#endif
#ifdef DEBUG_A11Y
// Very useful for debugging, please leave this here.
if (eventType.EqualsLiteral("AlertActive")) {
printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
}
if (localName.LowerCaseEqualsLiteral("textbox")) {
printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
}
#endif
nsAccessibilityService *accService = GetAccService();
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
nsCOMPtr<nsIWeakReference> weakShell =
nsCoreUtils::GetWeakShellFor(aTargetNode);
nsCoreUtils::GetWeakShellFor(origTarget);
if (!weakShell)
return NS_OK;
nsAccessible *accessible =
accService->GetAccessibleInWeakShell(aTargetNode, weakShell);
nsAccessible* accessible =
GetAccService()->GetAccessibleOrContainer(origTarget, weakShell);
if (eventType.EqualsLiteral("popuphiding"))
return HandlePopupHidingEvent(aTargetNode, accessible);
return HandlePopupHidingEvent(origTarget, accessible);
if (!accessible)
return NS_OK;
nsINode* targetNode = accessible->GetNode();
nsIContent* targetContent = targetNode->IsElement() ?
targetNode->AsElement() : nsnull;
#ifdef MOZ_XUL
PRBool isTree = targetContent ?
targetContent->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
kNameSpaceID_XUL) : PR_FALSE;
if (isTree) {
nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
NS_ASSERTION(treeAcc,
@ -587,7 +555,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
nsEventShell::FireEvent(accEvent);
if (isEnabled)
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
FireAccessibleFocusEvent(accessible, targetNode, aEvent);
return NS_OK;
}
@ -611,7 +579,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
// If it's a tree element, need the currently selected item
if (isTree) {
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
do_QueryInterface(aTargetNode);
do_QueryInterface(targetNode);
if (multiSelect) {
PRInt32 treeIndex = -1;
multiSelect->GetCurrentIndex(&treeIndex);
@ -641,9 +609,9 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
if (treeItemAccessible && eventType.EqualsLiteral("select")) {
// If multiselect tree, we should fire selectionadd or selection removed
if (gLastFocusedNode == aTargetNode) {
if (gLastFocusedNode == targetNode) {
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
do_QueryInterface(aTargetNode);
do_QueryInterface(targetNode);
nsAutoString selType;
multiSel->GetSelType(selType);
if (selType.IsEmpty() || !selType.EqualsLiteral("single")) {
@ -664,7 +632,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
else
#endif
if (eventType.EqualsLiteral("focus")) {
if (aTargetNode == mDocument && mDocument != gLastFocusedNode) {
if (targetNode == mDocument && mDocument != gLastFocusedNode) {
// Got focus event for the window, we will make sure that an accessible
// focus event for initial focus is fired. We do this on a short timer
// because the initial focus may not have been set yet.
@ -674,14 +642,13 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
// Keep a reference to the target node. We might want to change
// it to the individual radio button or selected item, and send
// the focus event to that.
nsCOMPtr<nsINode> focusedItem(aTargetNode);
nsCOMPtr<nsINode> focusedItem = targetNode;
if (!treeItemAccessible) {
nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
do_QueryInterface(aTargetNode);
do_QueryInterface(targetNode);
if (selectControl) {
nsCOMPtr<nsIDOMXULMenuListElement> menuList =
do_QueryInterface(aTargetNode);
do_QueryInterface(targetNode);
if (!menuList) {
// Don't do this for menu lists, the items only get focused
// when the list is open, based on DOMMenuitemActive events
@ -693,8 +660,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
if (!focusedItem)
return NS_OK;
accessible = accService->GetAccessibleInWeakShell(focusedItem,
weakShell);
accessible = GetAccService()->GetAccessibleInWeakShell(focusedItem,
weakShell);
if (!accessible)
return NS_OK;
}
@ -756,9 +723,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
if (!fireFocus) {
nsCOMPtr<nsINode> realFocusedNode = GetCurrentFocus();
nsCOMPtr<nsIContent> realFocusedContent = do_QueryInterface(realFocusedNode);
nsCOMPtr<nsIContent> targetContent = do_QueryInterface(aTargetNode);
nsIContent *containerContent = targetContent;
nsIContent* realFocusedContent = realFocusedNode->AsElement();
nsIContent* containerContent = targetContent;
while (containerContent) {
nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
if (popup || containerContent == realFocusedContent) {
@ -772,7 +738,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
if (fireFocus) {
// Always asynch, always from user input.
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE,
FireAccessibleFocusEvent(accessible, targetNode, aEvent, PR_TRUE,
PR_TRUE, eFromUserInput);
}
}
@ -787,7 +753,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
else if (eventType.EqualsLiteral("ValueChange")) {
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
aTargetNode, nsAccEvent::eRemoveDupes);
targetNode, nsAccEvent::eRemoveDupes);
}
#ifdef DEBUG
else if (eventType.EqualsLiteral("mouseover")) {
@ -798,31 +764,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
return NS_OK;
}
void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode)
{
*aTargetNode = nsnull;
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
if (!nsevent)
return;
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
nsCOMPtr<nsIDOMNode> eventTarget(do_QueryInterface(domEventTarget));
if (!eventTarget)
return;
nsIAccessibilityService* accService = GetAccService();
if (accService) {
nsresult rv = accService->GetRelevantContentNodeFor(eventTarget,
aTargetNode);
if (NS_SUCCEEDED(rv) && *aTargetNode)
return;
}
NS_ADDREF(*aTargetNode = eventTarget);
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessNode
@ -932,17 +873,6 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsAccessible*
nsRootAccessible::GetParent()
{
// Parent has been set in nsApplicationAccesible::AppendChild() when root
// accessible was initialized.
return mParent;
}
////////////////////////////////////////////////////////////////////////////////
// Protected members

View File

@ -87,7 +87,6 @@ public:
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsAccessible* GetParent();
// nsRootAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
@ -126,19 +125,12 @@ protected:
nsresult RemoveEventListeners();
/**
* Process DOM events.
*/
nsresult HandleEventWithTarget(nsIDOMEvent* aEvent, nsINode* aTargetNode);
static void GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode);
/**
* Process "popupshown" event. Used by HandleEventWithTarget().
* Process "popupshown" event. Used by HandleEvent().
*/
nsresult HandlePopupShownEvent(nsAccessible *aAccessible);
/*
* Process "popuphiding" event. Used by HandleEventWithTarget().
* Process "popuphiding" event. Used by HandleEvent().
*/
nsresult HandlePopupHidingEvent(nsINode *aNode, nsAccessible *aAccessible);

View File

@ -371,6 +371,7 @@ nsHTMLSelectListAccessible::CacheChildren()
void
nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
{
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
PRUint32 numChildren = aParentContent->GetChildCount();
for (PRUint32 count = 0; count < numChildren; count ++) {
nsIContent *childContent = aParentContent->GetChildAt(count);
@ -383,8 +384,9 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
tag == nsAccessibilityAtoms::optgroup) {
// Get an accessible for option or optgroup and cache it.
nsAccessible *accessible =
GetAccService()->GetAccessibleInWeakShell(childContent, mWeakShell);
nsRefPtr<nsAccessible> accessible =
GetAccService()->GetOrCreateAccessible(childContent, presShell,
mWeakShell);
if (accessible) {
mChildren.AppendElement(accessible);
accessible->SetParent(this);
@ -932,11 +934,19 @@ nsHTMLComboboxAccessible::CacheChildren()
if (!mListAccessible)
return;
mListAccessible->Init();
// Initialize and put into cache.
if (!mListAccessible->Init()) {
mListAccessible->Shutdown();
return;
}
}
mChildren.AppendElement(mListAccessible);
mListAccessible->SetParent(this);
// Cache combobox option accessibles so that we build complete accessible tree
// for combobox.
mListAccessible->EnsureChildren();
}
void
@ -1171,10 +1181,3 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
*aBoundingFrame = frame->GetParent();
aBounds = (*aBoundingFrame)->GetRect();
}
// nsHTMLComboboxListAccessible. nsAccessible public mehtod
nsAccessible*
nsHTMLComboboxListAccessible::GetParent()
{
return mParent;
}

View File

@ -276,7 +276,6 @@ public:
// nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
virtual nsAccessible* GetParent();
};
#endif

View File

@ -347,12 +347,6 @@ nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset
return NS_OK;
}
nsAccessible*
nsHTMLListBulletAccessible::GetParent()
{
return mParent;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLListAccessible
////////////////////////////////////////////////////////////////////////////////

View File

@ -129,8 +129,6 @@ public:
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength);
virtual nsAccessible* GetParent();
protected:
// XXX: Ideally we'd get the bullet text directly from the bullet frame via
// nsBulletFrame::GetListItemText(), but we'd need an interface for getting

View File

@ -1681,7 +1681,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
// Don't use frame from current accessible when we're hiding that
// accessible.
newAccessible = accessible->GetParent();
newAccessible = accessible->GetCachedParent();
} else {
newAccessible = accessible;
}

View File

@ -118,6 +118,8 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
if (!children)
return;
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
PRUint32 length = 0;
children->GetLength(&length);
@ -128,7 +130,8 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
continue;
nsCOMPtr<nsIContent> child(do_QueryInterface(DOMChild));
nsAccessible *accessible = GetAccService()->GetAttachedAccessibleFor(child);
nsRefPtr<nsAccessible> accessible =
GetAccService()->GetOrCreateAccessible(child, presShell, mWeakShell);
if (!accessible)
continue;

View File

@ -166,6 +166,8 @@ nsXULColorPickerAccessible::CacheChildren()
nsRefPtr<nsAccessible> child;
while ((child = walker.GetNextChild())) {
// XXX: do not call nsAccessible::GetRole() while accessible not in tree
// (bug 574588).
PRUint32 role = nsAccUtils::Role(child);
// Get an accessbile for menupopup or panel elements.

View File

@ -212,6 +212,8 @@ nsXULButtonAccessible::CacheChildren()
nsRefPtr<nsAccessible> child;
while ((child = walker.GetNextChild())) {
// XXX: do not call nsAccessible::GetRole() while accessible not in tree
// (bug 574588).
PRUint32 role = nsAccUtils::Role(child);
if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {

View File

@ -1040,12 +1040,6 @@ nsXULTreeItemAccessibleBase::GetStateInternal(PRUint32 *aState,
return NS_OK;
}
nsAccessible*
nsXULTreeItemAccessibleBase::GetParent()
{
return IsDefunct() ? nsnull : mParent.get();
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessibleBase: nsAccessible protected methods

View File

@ -199,7 +199,6 @@ public:
// nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsAccessible* GetParent();
// nsXULTreeItemAccessibleBase
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)

View File

@ -1202,12 +1202,6 @@ nsXULTreeGridCellAccessible::GetStateInternal(PRUint32 *aStates,
return NS_OK;
}
nsAccessible*
nsXULTreeGridCellAccessible::GetParent()
{
return IsDefunct() ? nsnull : mParent.get();
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: public implementation

View File

@ -162,8 +162,6 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsAccessible* GetParent();
// nsXULTreeGridCellAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)

View File

@ -127,6 +127,11 @@
try {
docAcc = docAcc.parent;
} catch (e) {
// XXX: it may randomaly fail on propertypage accessible of browser's
// tabbbrowser if nsIAccessible::parent returns cached parent only.
// This should gone after bug 572951.
// Error: failed | Can't get parent for [ 'panel1277435313424' ,
// role: propertypage]
ok(false, "Can't get parent for " + prettyName(docAcc));
throw e;
}

View File

@ -61,6 +61,7 @@
this.invoke = function removeChildSpan_invoke()
{
// remove HTML span, a first child of the node
ensureAccessibleTree(this.DOMNode);
this.DOMNode.removeChild(this.DOMNode.firstChild);
}

View File

@ -62,7 +62,7 @@ let TestPilotSetup = {
startupComplete: false,
_shortTimer: null,
_longTimer: null,
_remoteExperimentLoader: null,
_remoteExperimentLoader: null, // TODO make this a lazy initializer too?
taskList: [],
version: "",
@ -372,10 +372,16 @@ let TestPilotSetup = {
iconClass, showSubmit,
showAlwaysSubmitCheckbox,
linkText, linkUrl,
isExtensionUpdate) {
isExtensionUpdate,
onCloseCallback) {
/* TODO: Refactor the arguments of this function, it's getting really
* unweildly.... maybe pass in an object, or even make a notification an
* object that you create and then call .show() on. */
// If there are multiple windows, show notifications in the frontmost
// window.
let doc = this._getFrontBrowserWindow().document;
let window = this._getFrontBrowserWindow();
let doc = window.document;
let popup = doc.getElementById("pilot-notification-popup");
let anchor;
@ -422,14 +428,14 @@ let TestPilotSetup = {
"testpilot.notification.update"));
submitBtn.onclick = function() {
this._extensionUpdater.check(EXTENSION_ID);
self._hideNotification();
self._hideNotification(window, onCloseCallback);
};
} else {
submitBtn.setAttribute("label",
this._stringBundle.GetStringFromName("testpilot.submit"));
// Functionality for submit button:
submitBtn.onclick = function() {
self._hideNotification();
self._hideNotification(window, onCloseCallback);
if (showAlwaysSubmitCheckbox && alwaysSubmitCheckbox.checked) {
self._prefs.setValue(ALWAYS_SUBMIT_DATA, true);
}
@ -464,7 +470,7 @@ let TestPilotSetup = {
} else {
self._openChromeless(linkUrl);
}
self._hideNotification();
self._hideNotification(window, onCloseCallback);
}
};
link.setAttribute("hidden", false);
@ -473,7 +479,7 @@ let TestPilotSetup = {
}
closeBtn.onclick = function() {
self._hideNotification();
self._hideNotification(window, onCloseCallback);
};
// Show the popup:
@ -487,13 +493,19 @@ let TestPilotSetup = {
window.TestPilotWindowUtils.openChromeless(url);
},
_hideNotification: function TPS__hideNotification() {
let window = this._getFrontBrowserWindow();
_hideNotification: function TPS__hideNotification(window, onCloseCallback) {
/* Note - we take window as an argument instead of just using the frontmost
* window because the window order might have changed since the notification
* appeared and we want to be sure we close the notification in the same
* window as we opened it in! */
let popup = window.document.getElementById("pilot-notification-popup");
popup.hidden = true;
popup.setAttribute("open", "false");
popup.removeAttribute("tpisextensionupdate");
popup.hidePopup();
if (onCloseCallback) {
onCloseCallback();
}
},
_isShowingUpdateNotification : function() {
@ -543,11 +555,11 @@ let TestPilotSetup = {
if (this._prefs.getValue(POPUP_SHOW_ON_NEW, false)) {
for (i = 0; i < this.taskList.length; i++) {
task = this.taskList[i];
if (task.status == TaskConstants.STATUS_STARTING ||
if (task.status == TaskConstants.STATUS_PENDING ||
task.status == TaskConstants.STATUS_NEW) {
if (task.taskType == TaskConstants.TYPE_EXPERIMENT) {
this._showNotification(
task, true,
task, false,
this._stringBundle.formatStringFromName(
"testpilot.notification.newTestPilotStudy.message",
[task.title], 1),
@ -555,14 +567,16 @@ let TestPilotSetup = {
"testpilot.notification.newTestPilotStudy"),
"new-study", false, false,
this._stringBundle.GetStringFromName("testpilot.moreInfo"),
task.defaultUrl);
// Having shown the notification, update task status so that this
// notification won't be shown again.
task.changeStatus(TaskConstants.STATUS_IN_PROGRESS, true);
task.defaultUrl, false, function() {
/* on close callback (Bug 575767) -- when the "new study
* starting" popup is dismissed, then the study can start. */
task.changeStatus(TaskConstants.STATUS_IN_PROGRESS, true);
TestPilotSetup.reloadRemoteExperiments();
});
return;
} else if (task.taskType == TaskConstants.TYPE_SURVEY) {
this._showNotification(
task, true,
task, false,
this._stringBundle.formatStringFromName(
"testpilot.notification.newTestPilotSurvey.message",
[task.title], 1),

View File

@ -203,6 +203,7 @@ var TestPilotTask = {
},
onDetailPageOpened: function TestPilotTask_onDetailPageOpened(){
// TODO fold this into loadPage()?
},
checkDate: function TestPilotTask_checkDate() {
@ -444,14 +445,9 @@ TestPilotExperiment.prototype = {
},
experimentIsRunning: function TestPilotExperiment_isRunning() {
if (this._optInRequired) {
return (this._status == TaskConstants.STATUS_STARTING ||
this._status == TaskConstants.STATUS_IN_PROGRESS);
} else {
// Tests that don't require extra opt-in should start running even
// if you haven't seen them yet.
return (this._status < TaskConstants.STATUS_FINISHED);
}
// bug 575767
return (this._status == TaskConstants.STATUS_STARTING ||
this._status == TaskConstants.STATUS_IN_PROGRESS);
},
// Pass events along to handlers:
@ -599,11 +595,23 @@ TestPilotExperiment.prototype = {
}
}
// No-opt-in required tests skip PENDING and go straight to STARTING.
// If the notify-on-new-study pref is turned off, and the test doesn't
// require opt-in, then it can jump straight ahead to STARTING.
if (!this._optInRequired &&
this._status < TaskConstants.STATUS_STARTING &&
!Application.prefs.getValue("extensions.testpilot.popup.showOnNewStudy",
false) &&
(this._status == TaskConstants.STATUS_NEW ||
this._status == TaskConstants.STATUS_PENDING)) {
this._logger.info("Skipping pending and going straight to starting.");
this.changeStatus(TaskConstants.STATUS_STARTING, true);
}
// If a study is STARTING, and we're in the right date range,
// then start it, and move it to IN_PROGRESS.
if ( this._status == TaskConstants.STATUS_STARTING &&
currentDate >= this._startDate &&
currentDate <= this._endDate) {
this._logger.info("Study now starting.");
let uuidGenerator =
Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
let uuid = uuidGenerator.generateUUID().toString();

View File

@ -252,16 +252,12 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
}
/* Full Screen UI */
#fullscr-toggler {
display: none;
min-height: 1px;
height: 1px;
background: black;
border-style: none;
-moz-appearance: none;
}
#navigator-toolbox[inFullscreen="true"] > #fullscr-toggler,
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
display: -moz-box;
}

View File

@ -3518,12 +3518,10 @@ var FullScreen =
// events than raw listening of mouse coords.
let fullScrToggler = document.getElementById("fullscr-toggler");
if (!fullScrToggler) {
fullScrToggler = document.createElement("toolbar");
fullScrToggler = document.createElement("hbox");
fullScrToggler.id = "fullscr-toggler";
fullScrToggler.setAttribute("customizable", "false");
fullScrToggler.setAttribute("moz-collapsed", "true");
var navBar = document.getElementById("nav-bar");
navBar.parentNode.insertBefore(fullScrToggler, navBar);
fullScrToggler.collapsed = true;
gNavToolbox.parentNode.insertBefore(fullScrToggler, gNavToolbox.nextSibling);
}
fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
@ -3724,12 +3722,11 @@ var FullScreen =
this._collapseCallback, false);
}
var allFSToolbars = document.getElementsByTagNameNS(this._XULNS, "toolbar");
for (var i = 0; i < allFSToolbars.length; i++) {
if (allFSToolbars[i].getAttribute("fullscreentoolbar") == "true")
allFSToolbars[i].setAttribute("moz-collapsed", !aShow);
}
document.getElementById("fullscr-toggler").setAttribute("moz-collapsed", aShow);
// Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
// so we just move it off-screen instead. See bug 430687.
gNavToolbox.style.marginTop = aShow ? "" : -gNavToolbox.clientHeight + "px";
document.getElementById("fullscr-toggler").collapsed = aShow;
this._isChromeCollapsed = !aShow;
if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
this._shouldAnimate = true;

View File

@ -21,7 +21,7 @@
#
# Contributor(s):
# Mike Connor <mconnor@steelgryphon.com>
# Asaf Romano <mozilla.mano@sent.com>
# Asaf Romano <mano@mozilla.com>
#
# 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
@ -37,6 +37,8 @@
#
# ***** END LICENSE BLOCK *****
Components.utils.import("resource://gre/modules/AddonManager.jsm");
function restartApp() {
var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
.getService(Components.interfaces.nsIAppStartup);
@ -78,27 +80,21 @@ function deleteLocalstore() {
}
function disableAddons() {
// Disable addons
const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
var em = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
var type = nsIUpdateItem.TYPE_EXTENSION + nsIUpdateItem.TYPE_LOCALE;
var items = em.getItemList(type);
for (var i = 0; i < items.length; ++i)
em.disableItem(items[i].id);
// Select the default theme
var prefB = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
if (prefB.prefHasUserValue("general.skins.selectedSkin"))
prefB.clearUserPref("general.skins.selectedSkin");
// Disable plugins
var phs = Components.classes["@mozilla.org/plugin/host;1"]
.getService(Components.interfaces.nsIPluginHost);
var plugins = phs.getPluginTags();
for (i = 0; i < plugins.length; ++i)
plugins[i].disabled = true;
AddonManager.getAllAddons(function(aAddons) {
aAddons.forEach(function(aAddon) {
if (aAddon.type == "theme") {
// Setting userDisabled to false on the default theme activates it,
// disables all other themes and deactivates the applied persona, if
// any.
const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
if (aAddon.id == DEFAULT_THEME_ID)
aAddon.userDisabled = false;
}
else {
aAddon.userDisabled = true;
}
});
});
}
function restoreDefaultSearchEngines() {

View File

@ -43,7 +43,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
DIRS = src
ifdef ENABLE_TESTS
DIRS += tests

View File

@ -495,7 +495,15 @@ PlacesViewBase.prototype = {
if (elt.localName == "menupopup")
elt = elt.parentNode;
elt.label = aNewTitle || PlacesUIUtils.getBestTitle(aPlacesNode);
if (!aNewTitle && elt.localName != "toolbarbutton") {
// Many users consider toolbars as shortcuts containers, so explicitly
// allow empty labels on toolbarbuttons. For any other element try to be
// smarter, guessing a title from the uri.
elt.label = PlacesUIUtils.getBestTitle(aPlacesNode);
}
else {
elt.label = aNewTitle;
}
},
nodeRemoved:

View File

@ -1,381 +0,0 @@
/* -*- 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 Places.
*
* The Initial Developer of the Original Code is Mozilla Foundation
*
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Sungjoon Steve Won <stevewon@gmail.com> (Original Author)
* Asaf Romano <mano@mozilla.com>
*
* 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 ***** */
#include "nsISupports.idl"
#include "nsITransactionManager.idl"
interface nsIVariant;
interface nsIURI;
interface nsIMicrosummary;
interface nsITransaction;
/**
* nsIPlacesTransactionService is a service designed to handle
* nsITransactions that correspond to changes in Places. It is here as a
* service so that we can keep the transactions around without holding onto
* the global scope of a js window.
*
* NOTE: If you are interacting directly with the Places back-end, and you
* need to transactionalize a large amount of changes, look at
* nsINavBookmarksService.runInBatchMode.
*/
[scriptable, uuid(32eee5da-2bc7-4d18-8a54-a8ff0dec4d2a)]
interface nsIPlacesTransactionsService : nsITransactionManager
{
/**
* Transaction for performing several Places Transactions in a single batch.
*
* @param aName
* title of the aggregate transactions
* @param aTransactions
* an array of transactions to perform
* @returns nsITransaction object
*/
nsITransaction aggregateTransactions(in AString aName,
in nsIVariant aTransactions);
/**
* Transaction for creating a new folder item.
*
* @param aName
* the name of the new folder
* @param aContainerId
* the identifier of the folder in which the new folder should be
* added.
* @param [optional] aIndex
* the index of the item in aContainer, pass -1 or nothing to create
* the item at the end of aContainer.
* @param [optional] aAnnotations
* the annotations to set for the new folder.
* @param [optional] aChildItemsTransactions
* array of transactions for items to be created under the new folder.
* @returns nsITransaction object
*/
nsITransaction createFolder(in AString aName, in long long aContainerId,
[optional] in long long aIndex,
[optional] in nsIVariant aAnnotations,
[optional] in nsIVariant aChildItemsTransactions);
/**
* Transaction for creating a new bookmark item
*
* @param aURI
* the uri of the new bookmark (nsIURI)
* @param aContainerId
* the identifier of the folder in which the bookmark should be added.
* @param [optional] aIndex
* the index of the item in aContainer, pass -1 or nothing to create
* the item at the end of aContainer.
* @param [optional] aTitle
* the title of the new bookmark.
* @param [optional] aKeyword
* the keyword of the new bookmark.
* @param [optional] aAnnotations
* the annotations to set for the new bookmark.
* @param [optional] aChildTransactions
* child transactions to commit after creating the bookmark. Prefer
* using any of the arguments above if possible. In general, a child
* transations should be used only if the change it does has to be
* reverted manually when removing the bookmark item.
* a child transaction must support setting its bookmark-item
* identifier via an "id" js setter.
* @returns nsITransaction object
*/
nsITransaction createItem(in nsIURI aURI, in long long aContainerId,
[optional] in long long aIndex,
[optional] in AString aTitle,
[optional] in AString aKeyword,
[optional] in nsIVariant aAnnotations,
[optional] in nsIVariant aChildTransactions);
/**
* Transaction for creating a new separator item
*
* @param aContainerId
* the identifier of the folder in which the separator should be
* added.
* @param [optional] aIndex
* the index of the item in aContainer, pass -1 or nothing to create
* the separator at the end of aContainer.
* @returns nsITransaction object
*/
nsITransaction createSeparator(in long long aContainerId,
[optional] in long long aIndex);
/**
* Transaction for creating a new live-bookmark item.
*
* @see nsILivemarksService::createLivemark for documentation regarding the
* first three arguments.
*
* @param aContainerId
* the identifier of the folder in which the live-bookmark should be
* added.
* @param [optional] aIndex
* the index of the item in aContainer, pass -1 or nothing to create
* the item at the end of aContainer.
* @param [optional] aAnnotations
* the annotations to set for the new live-bookmark.
* @returns nsITransaction object
*/
nsITransaction createLivemark(in nsIURI aFeedURI,
in nsIURI aSiteURI,
in AString aName,
in long long aContainerId,
[optional] in long long aIndex,
[optional] in nsIVariant aAnnotations);
/**
* Transaction for moving an Item.
*
* @param aItemId
* the id of the item to move
* @param aNewContainerId
* id of the new container to move to
* @param aNewIndex
* index of the new position to move to
* @returns nsITransaction object
*/
nsITransaction moveItem(in long long aItemId,
in long long aNewContainerId,
in long long aNewIndex);
/**
* Transaction for removing an Item
*
* @param aItemId
* id of the item to remove
* @returns nsITransaction object
*/
nsITransaction removeItem(in long long aItemId);
/**
* Transaction for editting a bookmark's title.
*
* @param aItemId
* id of the item to edit
* @param aNewTitle
* new title for the item to edit
* @returns nsITransaction object
*/
nsITransaction editItemTitle(in long long aItemId, in AString aNewTitle);
/**
* Transaction for editing a bookmark's uri.
*
* @param aBookmarkId
* id of the bookmark to edit
* @param aNewURI
* new uri for the bookmark
* @returns nsITransaction object
*/
nsITransaction editBookmarkURI(in long long aBookmarkId, in nsIURI aNewURI);
/**
* Transaction for setting/unsetting an item annotation
*
* @param aItemId
* id of the item where to set annotation
* @param aAnnotationObject
* Object representing an annotation, containing the following
* properties: name, flags, expires, type, mimeType (only used for
* binary annotations), value.
* If value is null the annotation will be removed
* @returns nsITransaction object
*/
nsITransaction setItemAnnotation(in nsIVariant aItemId,
in nsIVariant aAnnotationObject);
/**
* Transaction for setting/unsetting a page annotation
*
* @param aURI
* URI of the page where to set annotation
* @param aAnnotationObject
* Object representing an annotation, containing the following
* properties: name, flags, expires, type, mimeType (only used for
* binary annotations), value.
* If value is null the annotation will be removed
* @returns nsITransaction object
*/
nsITransaction setPageAnnotation(in nsIURI aURI,
in nsIVariant aAnnotationObject);
/**
* Transaction for setting/unsetting Load-in-sidebar annotation
*
* @param aBookmarkId
* id of the bookmark where to set Load-in-sidebar annotation
* @param aLoadInSidebar
* boolean value
* @returns nsITransaction object
*/
nsITransaction setLoadInSidebar(in long long aBookmarkId,
in boolean aLoadInSidebar);
/**
* Transaction for editing a the description of a bookmark or a folder
*
* @param aItemId
* id of the item to edit
* @param aDescription
* new description
* @returns nsITransaction object
*/
nsITransaction editItemDescription(in long long aItemId,
in AString aDescription);
/**
* Transaction for editing a bookmark's keyword.
*
* @param aBookmarkId
* id of the bookmark to edit
* @param aNewKeyword
* new keyword for the bookmark
* @returns nsITransaction object
*/
nsITransaction editBookmarkKeyword(in long long aBookmarkId,
in AString aNewKeyword);
/**
* Transaction for editing the post data associated with a bookmark.
*
* @param aBookmarkId
* id of the bookmark to edit
* @param aPostData
* post data
* @returns nsITransaction object
*/
nsITransaction editBookmarkPostData(in long long aBookmarkId,
in AString aPostData);
/**
* Transaction for editing a live bookmark's site URI.
*
* @param aLivemarkId
* id of the livemark
* @param aURI
* new site uri
* @returns nsITransaction object
*/
nsITransaction editLivemarkSiteURI(in long long aLivemarkId, in nsIURI aURI);
/**
* Transaction for editting a live bookmark's feed URI.
*
* @param aLivemarkId
* id of the livemark
* @param aURI
* new feed uri
* @returns nsITransaction object
*/
nsITransaction editLivemarkFeedURI(in long long aLivemarkId, in nsIURI aURI);
/**
* Transaction for editing a bookmark's microsummary.
*
* @param aBookmarkId
* id of the bookmark to edit
* @param aNewMicrosummary
* new microsummary for the bookmark
* @returns nsITransaction object
*/
nsITransaction editBookmarkMicrosummary(in long long aBookmarkId,
in nsIMicrosummary aNewMicrosummary);
/**
* Transaction for editing an item's date added property.
*
* @param aItemId
* id of the item to edit
* @param aNewDateAdded
* new date added for the item
* @returns nsITransaction object
*/
nsITransaction editItemDateAdded(in long long aItemId,
in PRTime aNewDateAdded);
/**
* Transaction for editing an item's last modified time.
*
* @param aItemId
* id of the item to edit
* @param aNewLastModified
* new last modified date for the item
* @returns nsITransaction object
*/
nsITransaction editItemLastModified(in long long aItemId,
in PRTime aNewLastModified);
/**
* Transaction for sorting a folder by name
*
* @param aFolderId
* id of the folder to sort
* @returns nsITransaction object
*/
nsITransaction sortFolderByName(in long long aFolderId);
/**
* Transaction for tagging a URL with the given set of tags. Current tags set
* for the URL persist. It's the caller's job to check whether or not aURI
* was already tagged by any of the tags in aTags, undoing this tags
* transaction removes them all from aURL!
*
* @param aURI
* the URL to tag.
* @param aTags
* Array of tags to set for the given URL.
*/
nsITransaction tagURI(in nsIURI aURI, in nsIVariant aTags);
/**
* Transaction for removing tags from a URL. It's the caller's job to check
* whether or not aURI isn't tagged by any of the tags in aTags, undoing this
* tags transaction adds them all to aURL!
*
* @param aURI
* the URL to un-tag.
* @param aTags
* Array of tags to unset. pass null to remove all tags from the given
* url.
*/
nsITransaction untagURI(in nsIURI aURI, in nsIVariant aTags);
};

View File

@ -1,4 +1,2 @@
component {c0844a84-5a12-4808-80a8-809cb002bb4f} nsPlacesTransactionsService.js
contract @mozilla.org/browser/placesTransactionsService;1 {c0844a84-5a12-4808-80a8-809cb002bb4f}
component {6bcb9bde-9018-4443-a071-c32653469597} PlacesProtocolHandler.js
contract @mozilla.org/network/protocol;1?name=place {6bcb9bde-9018-4443-a071-c32653469597}

View File

@ -46,7 +46,6 @@ include $(DEPTH)/config/autoconf.mk
EXTRA_COMPONENTS = \
BrowserPlaces.manifest \
nsPlacesTransactionsService.js \
PlacesProtocolHandler.js \
$(NULL)

View File

@ -72,7 +72,7 @@ var PlacesUIUtils = {
* @returns A URI object for the spec.
*/
createFixedURI: function PUIU_createFixedURI(aSpec) {
return this.URIFixup.createFixupURI(aSpec, 0);
return URIFixup.createFixupURI(aSpec, 0);
},
/**
@ -89,11 +89,11 @@ var PlacesUIUtils = {
},
getFormattedString: function PUIU_getFormattedString(key, params) {
return this._bundle.formatStringFromName(key, params, params.length);
return bundle.formatStringFromName(key, params, params.length);
},
getString: function PUIU_getString(key) {
return this._bundle.GetStringFromName(key);
return bundle.GetStringFromName(key);
},
/**
@ -660,7 +660,7 @@ var PlacesUIUtils = {
},
_getCurrentActiveWin: function PUIU__getCurrentActiveWin() {
return this.fm.activeWindow;
return focusManager.activeWindow;
},
/**
@ -1221,7 +1221,7 @@ var PlacesUIUtils = {
var queryName = "";
// If the let pane hasn't been built, use the annotation service
// directly, to avoid building the left pane too early.
if (this.__lookupGetter__("leftPaneFolderId")) {
if (Object.getOwnPropertyDescriptor(this, "leftPaneFolderId").value === undefined) {
try {
queryName = PlacesUtils.annotations.
getItemAnnotation(aItemId, this.ORGANIZER_QUERY_ANNO);
@ -1240,8 +1240,7 @@ var PlacesUIUtils = {
}
}
return queryName;
},
}
};
XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "RDF",
@ -1252,14 +1251,6 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "localStore", function() {
return PlacesUIUtils.RDF.GetDataSource("rdf:local-store");
});
XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "ptm",
"@mozilla.org/browser/placesTransactionsService;1",
"nsIPlacesTransactionsService");
XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "URIFixup",
"@mozilla.org/docshell/urifixup;1",
"nsIURIFixup");
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
return Services.prefs.getComplexValue("intl.ellipsis",
Ci.nsIPrefLocalizedString).data;
@ -1269,7 +1260,11 @@ XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "privateBrowsing",
"@mozilla.org/privatebrowsing;1",
"nsIPrivateBrowsingService");
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "_bundle", function() {
XPCOMUtils.defineLazyServiceGetter(this, "URIFixup",
"@mozilla.org/docshell/urifixup;1",
"nsIURIFixup");
XPCOMUtils.defineLazyGetter(this, "bundle", function() {
const PLACES_STRING_BUNDLE_URI =
"chrome://browser/locale/places/places.properties";
return Cc["@mozilla.org/intl/stringbundle;1"].
@ -1277,6 +1272,177 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "_bundle", function() {
createBundle(PLACES_STRING_BUNDLE_URI);
});
XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "fm",
XPCOMUtils.defineLazyServiceGetter(this, "focusManager",
"@mozilla.org/focus-manager;1",
"nsIFocusManager");
/**
* This is a compatibility shim for old PUIU.ptm users.
*
* If you're looking for transactions and writing new code using them, directly
* use the transactions objects exported by the PlacesUtils.jsm module.
*
* This object will be removed once enough users are converted to the new API.
*/
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ptm", function() {
// Ensure PlacesUtils is imported in scope.
PlacesUtils;
return {
aggregateTransactions: function(aName, aTransactions)
new PlacesAggregatedTransaction(aName, aTransactions),
createFolder: function(aName, aContainer, aIndex, aAnnotations,
aChildItemsTransactions)
new PlacesCreateFolderTransaction(aName, aContainer, aIndex, aAnnotations,
aChildItemsTransactions),
createItem: function(aURI, aContainer, aIndex, aTitle, aKeyword,
aAnnotations, aChildTransactions)
new PlacesCreateBookmarkTransaction(aURI, aContainer, aIndex, aTitle,
aKeyword, aAnnotations,
aChildTransactions),
createSeparator: function(aContainer, aIndex)
new PlacesCreateSeparatorTransaction(aContainer, aIndex),
createLivemark: function(aFeedURI, aSiteURI, aName, aContainer, aIndex,
aAnnotations)
new PlacesCreateLivemarkTransaction(aFeedURI, aSiteURI, aName, aContainer,
aIndex, aAnnotations),
moveItem: function(aItemId, aNewContainer, aNewIndex)
new PlacesMoveItemTransaction(aItemId, aNewContainer, aNewIndex),
removeItem: function(aItemId)
new PlacesRemoveItemTransaction(aItemId),
editItemTitle: function(aItemId, aNewTitle)
new PlacesEditItemTitleTransaction(aItemId, aNewTitle),
editBookmarkURI: function(aItemId, aNewURI)
new PlacesEditBookmarkURITransaction(aItemId, aNewURI),
setItemAnnotation: function(aItemId, aAnnotationObject)
new PlacesSetItemAnnotationTransaction(aItemId, aAnnotationObject),
setPageAnnotation: function(aURI, aAnnotationObject)
new PlacesSetPageAnnotationTransaction(aURI, aAnnotationObject),
editBookmarkKeyword: function(aItemId, aNewKeyword)
new PlacesEditBookmarkKeywordTransaction(aItemId, aNewKeyword),
editBookmarkPostData: function(aItemId, aPostData)
new PlacesEditBookmarkPostDataTransaction(aItemId, aPostData),
editLivemarkSiteURI: function(aLivemarkId, aSiteURI)
new PlacesEditLivemarkSiteURITransaction(aLivemarkId, aSiteURI),
editLivemarkFeedURI: function(aLivemarkId, aFeedURI)
new PlacesEditLivemarkFeedURITransaction(aLivemarkId, aFeedURI),
editBookmarkMicrosummary: function(aItemId, aNewMicrosummary)
new PlacesEditBookmarkMicrosummaryTransaction(aItemId, aNewMicrosummary),
editItemDateAdded: function(aItemId, aNewDateAdded)
new PlacesEditItemDateAddedTransaction(aItemId, aNewDateAdded),
editItemLastModified: function(aItemId, aNewLastModified)
new PlacesEditItemLastModifiedTransaction(aItemId, aNewLastModified),
sortFolderByName: function(aFolderId)
new PlacesSortFolderByNameTransaction(aFolderId),
tagURI: function(aURI, aTags)
new PlacesTagURITransaction(aURI, aTags),
untagURI: function(aURI, aTags)
new PlacesUntagURITransaction(aURI, aTags),
/**
* Transaction for setting/unsetting Load-in-sidebar annotation.
*
* @param aBookmarkId
* id of the bookmark where to set Load-in-sidebar annotation.
* @param aLoadInSidebar
* boolean value.
* @returns nsITransaction object.
*/
setLoadInSidebar: function(aItemId, aLoadInSidebar)
{
let annoObj = { name: PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
type: Ci.nsIAnnotationService.TYPE_INT32,
flags: 0,
value: aLoadInSidebar,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
return new PlacesSetItemAnnotationTransaction(aItemId, annoObj);
},
/**
* Transaction for editing a the description of a bookmark or a folder.
*
* @param aItemId
* id of the item to edit.
* @param aDescription
* new description.
* @returns nsITransaction object.
*/
editItemDescription: function(aItemId, aDescription)
{
let annoObj = { name: PlacesUIUtils.DESCRIPTION_ANNO,
type: Ci.nsIAnnotationService.TYPE_STRING,
flags: 0,
value: aDescription,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
return new PlacesSetItemAnnotationTransaction(aItemId, annoObj);
},
////////////////////////////////////////////////////////////////////////////
//// nsITransactionManager forwarders.
beginBatch: function()
PlacesUtils.transactionManager.beginBatch(),
endBatch: function()
PlacesUtils.transactionManager.endBatch(),
doTransaction: function(txn)
PlacesUtils.transactionManager.doTransaction(txn),
undoTransaction: function()
PlacesUtils.transactionManager.undoTransaction(),
redoTransaction: function()
PlacesUtils.transactionManager.redoTransaction(),
get numberOfUndoItems()
PlacesUtils.transactionManager.numberOfUndoItems,
get numberOfRedoItems()
PlacesUtils.transactionManager.numberOfRedoItems,
get maxTransactionCount()
PlacesUtils.transactionManager.maxTransactionCount,
set maxTransactionCount(val)
PlacesUtils.transactionManager.maxTransactionCount = val,
clear: function()
PlacesUtils.transactionManager.clear(),
peekUndoStack: function()
PlacesUtils.transactionManager.peekUndoStack(),
peekRedoStack: function()
PlacesUtils.transactionManager.peekRedoStack(),
getUndoStack: function()
PlacesUtils.transactionManager.getUndoStack(),
getRedoStack: function()
PlacesUtils.transactionManager.getRedoStack(),
AddListener: function(aListener)
PlacesUtils.transactionManager.AddListener(aListener),
RemoveListener: function(aListener)
PlacesUtils.transactionManager.RemoveListener(aListener)
}
});

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,7 @@ function startTest() {
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"bm2");
bs.setItemTitle(id, "bm2_edited");
bs.setItemTitle(id, "");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
@ -135,7 +135,7 @@ function startTest() {
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"tb2");
bs.setItemTitle(id, "tb2_edited");
bs.setItemTitle(id, "");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
@ -285,9 +285,13 @@ var bookmarksObserver = {
var tree = sidebar.contentDocument.getElementById("bookmarks-view");
let cellText = tree.view.getCellText(aElementOrTreeIndex,
tree.columns.getColumnAt(0));
if (!aNewValue)
return cellText == PlacesUIUtils.getBestTitle(tree.view.nodeForTreeIndex(aElementOrTreeIndex));
return cellText == aNewValue;
}
else {
if (!aNewValue && aElementOrTreeIndex.localName != "toolbarbutton")
return aElementOrTreeIndex.label == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
return aElementOrTreeIndex.label == aNewValue;
}
};

View File

@ -38,50 +38,12 @@
*
* ***** END LICENSE BLOCK ***** */
// Get bookmark service
try {
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
} catch(ex) {
do_throw("Could not get nav-bookmarks-service\n");
}
// Get livemark service
try {
var lmsvc = Cc["@mozilla.org/browser/livemark-service;2"].getService(Ci.nsILivemarkService);
} catch(ex) {
do_throw("Could not get livemark-service\n");
}
// Get microsummary service
try {
var mss = Cc["@mozilla.org/microsummary/service;1"].getService(Ci.nsIMicrosummaryService);
} catch(ex) {
do_throw("Could not get microsummary-service\n");
}
// Get Places Transaction Manager Service
try {
var ptSvc = Cc["@mozilla.org/browser/placesTransactionsService;1"].
getService(Ci.nsIPlacesTransactionsService);
} catch(ex) {
do_throw("Could not get Places Transactions Service\n");
}
// Get tagging service
try {
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
getService(Ci.nsITaggingService);
} catch(ex) {
do_throw("Could not get tagging service\n");
}
// Get annotations service
try {
var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
} catch(ex) {
do_throw("Could not get annotations service\n");
}
var bmsvc = PlacesUtils.bookmarks;
var lmsvc = PlacesUtils.livemarks;
var mss = PlacesUtils.microsummaries;
var ptSvc = PlacesUIUtils.ptm;
var tagssvc = PlacesUtils.tagging;
var annosvc = PlacesUtils.annotations;
// create and add bookmarks observer
var observer = {
@ -143,9 +105,8 @@ function run_test() {
var root = bmsvc.bookmarksMenuFolder;
//Test creating a folder with a description
const DESCRIPTION_ANNO = "bookmarkProperties/description";
const TEST_DESCRIPTION = "this is my test description";
var annos = [{ name: DESCRIPTION_ANNO,
var annos = [{ name: PlacesUIUtils.DESCRIPTION_ANNO,
type: annosvc.TYPE_STRING,
flags: 0,
value: TEST_DESCRIPTION,
@ -165,7 +126,7 @@ function run_test() {
do_check_eq(observer._itemAddedParent, root);
do_check_eq(observer._itemAddedId, folderId);
do_check_eq(TEST_DESCRIPTION,
annosvc.getItemAnnotation(folderId, DESCRIPTION_ANNO));
annosvc.getItemAnnotation(folderId, PlacesUIUtils.DESCRIPTION_ANNO));
txn1.undoTransaction();
do_check_eq(observer._itemRemovedId, folderId);
@ -415,11 +376,11 @@ function run_test() {
do_check_eq(observer._itemChangedProperty, "uri");
do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
// Test edit item description
// Test edit description transaction.
var txn10 = ptSvc.editItemDescription(bkmk1Id, "Description1");
txn10.doTransaction();
do_check_eq(observer._itemChangedId, bkmk1Id);
do_check_eq(observer._itemChangedProperty, "bookmarkProperties/description");
do_check_eq(observer._itemChangedProperty, PlacesUIUtils.DESCRIPTION_ANNO);
// Testing edit keyword
var txn11 = ptSvc.editBookmarkKeyword(bkmk1Id, "kw1");
@ -510,16 +471,15 @@ function run_test() {
do_check_false(lmsvc.isLivemark(lvmkId));
do_check_eq(observer._itemRemovedId, lvmkId);
// Test setLoadInSidebar
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
// Test LoadInSidebar transaction.
var txn16 = ptSvc.setLoadInSidebar(bkmk1Id, true);
txn16.doTransaction();
do_check_eq(observer._itemChangedId, bkmk1Id);
do_check_eq(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
do_check_eq(observer._itemChanged_isAnnotationProperty, true);
txn16.undoTransaction();
do_check_eq(observer._itemChangedId, bkmk1Id);
do_check_eq(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
do_check_eq(observer._itemChanged_isAnnotationProperty, true);
// Test generic item annotation

View File

@ -1,89 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
* ***** 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
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net>
*
* 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 test will ensure any transactions service that is going to create
* a new item, won't replace the GUID when undoing and redoing the action.
*/
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var txnsvc = Cc["@mozilla.org/browser/placesTransactionsService;1"].
getService(Ci.nsIPlacesTransactionsService);
function test_GUID_persistance(aTxn) {
aTxn.doTransaction();
var itemId = bmsvc.getIdForItemAt(bmsvc.unfiledBookmarksFolder, 0);
var GUID = bmsvc.getItemGUID(itemId);
aTxn.undoTransaction();
aTxn.redoTransaction();
do_check_eq(GUID, bmsvc.getItemGUID(itemId));
aTxn.undoTransaction();
}
function run_test() {
// Create folder.
var createFolderTxn = txnsvc.createFolder("Test folder",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create bookmark.
var createBookmarkTxn = txnsvc.createItem(uri("http://www.example.com"),
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX,
"Test bookmark");
test_GUID_persistance(createBookmarkTxn);
// Create separator.
var createSeparatorTxn = txnsvc.createSeparator(bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create livemark.
var createLivemarkTxn = txnsvc.createLivemark(uri("http://feeduri.com"),
uri("http://siteuri.com"),
"Test livemark",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createLivemarkTxn);
// Tag URI.
var tagURITxn = txnsvc.tagURI(uri("http://www.example.com"), ["foo"]);
test_GUID_persistance(tagURITxn);
}
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
* ***** 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
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net>
*
* 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 test will ensure any transactions service that is going to create
* a new item, won't replace the GUID when undoing and redoing the action.
*/
var bmsvc = PlacesUtils.bookmarks;
var txnsvc = PlacesUIUtils.ptm;
function test_GUID_persistance(aTxn) {
aTxn.doTransaction();
var itemId = bmsvc.getIdForItemAt(bmsvc.unfiledBookmarksFolder, 0);
var GUID = bmsvc.getItemGUID(itemId);
aTxn.undoTransaction();
aTxn.redoTransaction();
do_check_eq(GUID, bmsvc.getItemGUID(itemId));
aTxn.undoTransaction();
}
function run_test() {
// Create folder.
var createFolderTxn = txnsvc.createFolder("Test folder",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create bookmark.
var createBookmarkTxn = txnsvc.createItem(uri("http://www.example.com"),
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX,
"Test bookmark");
test_GUID_persistance(createBookmarkTxn);
// Create separator.
var createSeparatorTxn = txnsvc.createSeparator(bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create livemark.
var createLivemarkTxn = txnsvc.createLivemark(uri("http://feeduri.com"),
uri("http://siteuri.com"),
"Test livemark",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createLivemarkTxn);
// Tag URI.
var tagURITxn = txnsvc.tagURI(uri("http://www.example.com"), ["foo"]);
test_GUID_persistance(tagURITxn);
}

View File

@ -119,7 +119,6 @@
@BINPATH@/components/autocomplete.xpt
@BINPATH@/components/autoconfig.xpt
@BINPATH@/components/browsercompsbase.xpt
@BINPATH@/components/browserplaces.xpt
@BINPATH@/components/browser-feeds.xpt
@BINPATH@/components/caps.xpt
@BINPATH@/components/chardet.xpt
@ -280,7 +279,6 @@
@BINPATH@/components/nsSetDefaultBrowser.js
@BINPATH@/components/nsMicrosummaryService.js
@BINPATH@/components/BrowserPlaces.manifest
@BINPATH@/components/nsPlacesTransactionsService.js
@BINPATH@/components/nsPrivateBrowsingService.manifest
@BINPATH@/components/nsPrivateBrowsingService.js
@BINPATH@/components/toolkitsearch.manifest

View File

@ -555,7 +555,6 @@ xpicleanup@BIN_SUFFIX@
components/autoconfig.xpt
components/browser-feeds.xpt
components/browsercompsbase.xpt
components/browserplaces.xpt
components/browsersearch.xpt
components/caps.xpt
components/chardet.xpt
@ -861,3 +860,5 @@ extensions/inspector@mozilla.org/platform/WINNT/chrome/icons/default/winInspecto
extensions/inspector@mozilla.org/components/inspector.xpt
extensions/inspector@mozilla.org/components/@DLL_PREFIX@inspector@DLL_SUFFIX@
extensions/inspector@mozilla.org/chrome/icons/default/winInspectorMain.ico
components/nsPlacesTransactionsService.js
components/browserplaces.xpt

Binary file not shown.

Before

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -985,7 +985,7 @@ toolbar[iconsize="small"] #fullscreen-button {
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
/* Notification icon box */
@ -994,7 +994,7 @@ toolbar[iconsize="small"] #fullscreen-button {
}
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
width: 16px;
height: 16px;
}

View File

@ -10,7 +10,8 @@ browser.jar:
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/Geo.png
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Go-arrow.png
skin/classic/browser/identity.png
skin/classic/browser/Info.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -1810,7 +1810,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
margin-top: -3px;
margin-left: -23px;
min-width: 280px;
-moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat;
-moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat;
}
#notification-popup {
@ -1823,7 +1823,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
width: 16px;
height: 16px;
margin: 0 2px;
@ -1840,7 +1840,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
#identity-popup-container,

View File

@ -10,7 +10,8 @@ browser.jar:
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/feed-icons.png
skin/classic/browser/fullscreen-video.css
skin/classic/browser/Geo.png
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Go-arrow.png
skin/classic/browser/home.png
skin/classic/browser/hud-panel.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -29,6 +29,10 @@
margin-top: 8px;
}
#main-window[sizemode="normal"][chromemargin^="0,"] {
margin-top: 2px;
}
#main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
-moz-appearance: none;
background-color: #556;
@ -53,7 +57,7 @@
#navigator-toolbox[tabsontop="true"] > #TabsToolbar,
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar,
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar:last-child,
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#fullscr-toggler):-moz-lwtheme {
#navigator-toolbox > toolbar:not(#toolbar-menubar):-moz-lwtheme {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
}

View File

@ -1603,7 +1603,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
/* Notification icon box */
@ -1612,7 +1612,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geo.png);
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
width: 16px;
height: 16px;
}

View File

@ -13,7 +13,8 @@ browser.jar:
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/Geo.png (Geo.png)
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Info.png (Info.png)
skin/classic/browser/identity.png (identity.png)
skin/classic/browser/keyhole-forward-mask.svg
@ -98,7 +99,8 @@ browser.jar:
* skin/classic/aero/browser/browser.css (browser-aero.css)
* skin/classic/aero/browser/engineManager.css (engineManager.css)
skin/classic/aero/browser/fullscreen-video.css
skin/classic/aero/browser/Geo.png (Geo-aero.png)
skin/classic/aero/browser/Geolocation-16.png
skin/classic/aero/browser/Geolocation-64.png
skin/classic/aero/browser/Info.png (Info-aero.png)
skin/classic/aero/browser/identity.png (identity-aero.png)
skin/classic/aero/browser/keyhole-forward-mask.svg

View File

@ -47,12 +47,22 @@ LIBRARY_NAME = chrome_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORTS_NAMESPACES = mozilla/chrome
EXPORTS_mozilla/chrome = \
RegistryMessageUtils.h \
$(NULL)
CPPSRCS = \
nsChromeRegistry.cpp \
nsChromeRegistryChrome.cpp \
nsChromeProtocolHandler.cpp \
$(NULL)
ifdef MOZ_IPC
CPPSRCS += nsChromeRegistryContent.cpp
endif
EXTRA_DSO_LDOPTS = \
$(MOZ_UNICHARUTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \
@ -66,8 +76,15 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
EXTRA_DSO_LDOPTS += $(TK_LIBS)
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(topsrcdir)/netwerk/protocol/res \
-I$(topsrcdir)/netwerk/base/src \
$(NULL)
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
endif

View File

@ -0,0 +1,208 @@
/* -*- Mode: C++; tab-width: 8; 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) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net> (Initial Developer)
*
* 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 ***** */
#ifndef mozilla_RegistryMessageUtils_h
#define mozilla_RegistryMessageUtils_h
#include "IPC/IPCMessageUtils.h"
#include "nsStringGlue.h"
struct SerializedURI
{
nsCString spec;
nsCString charset;
};
struct ChromePackage
{
nsCString package;
SerializedURI contentBaseURI;
SerializedURI localeBaseURI;
SerializedURI skinBaseURI;
PRUint32 flags;
};
struct ResourceMapping
{
nsCString resource;
SerializedURI resolvedURI;
};
struct OverrideMapping
{
SerializedURI originalURI;
SerializedURI overrideURI;
};
namespace IPC {
template<>
struct ParamTraits<SerializedURI>
{
typedef SerializedURI paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.spec);
WriteParam(aMsg, aParam.charset);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
nsCString spec, charset;
if (ReadParam(aMsg, aIter, &spec) &&
ReadParam(aMsg, aIter, &charset)) {
aResult->spec = spec;
aResult->charset = charset;
return true;
}
return false;
}
};
template <>
struct ParamTraits<ChromePackage>
{
typedef ChromePackage paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.package);
WriteParam(aMsg, aParam.contentBaseURI);
WriteParam(aMsg, aParam.localeBaseURI);
WriteParam(aMsg, aParam.skinBaseURI);
WriteParam(aMsg, aParam.flags);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
nsCString package;
SerializedURI contentBaseURI, localeBaseURI, skinBaseURI;
PRUint32 flags;
if (ReadParam(aMsg, aIter, &package) &&
ReadParam(aMsg, aIter, &contentBaseURI) &&
ReadParam(aMsg, aIter, &localeBaseURI) &&
ReadParam(aMsg, aIter, &skinBaseURI) &&
ReadParam(aMsg, aIter, &flags)) {
aResult->package = package;
aResult->contentBaseURI = contentBaseURI;
aResult->localeBaseURI = localeBaseURI;
aResult->skinBaseURI = skinBaseURI;
aResult->flags = flags;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%s, %s, %s, %s, %u]", aParam.package.get(),
aParam.contentBaseURI.spec.get(),
aParam.localeBaseURI.spec.get(),
aParam.skinBaseURI.spec.get(), aParam.flags));
}
};
template <>
struct ParamTraits<ResourceMapping>
{
typedef ResourceMapping paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.resource);
WriteParam(aMsg, aParam.resolvedURI);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
nsCString resource;
SerializedURI resolvedURI;
if (ReadParam(aMsg, aIter, &resource) &&
ReadParam(aMsg, aIter, &resolvedURI)) {
aResult->resource = resource;
aResult->resolvedURI = resolvedURI;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%s, %s, %u]", aParam.resource.get(),
aParam.resolvedURI.spec.get()));
}
};
template <>
struct ParamTraits<OverrideMapping>
{
typedef OverrideMapping paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.originalURI);
WriteParam(aMsg, aParam.overrideURI);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
SerializedURI originalURI;
SerializedURI overrideURI;
if (ReadParam(aMsg, aIter, &originalURI) &&
ReadParam(aMsg, aIter, &overrideURI)) {
aResult->originalURI = originalURI;
aResult->overrideURI = overrideURI;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%s, %s, %u]", aParam.originalURI.spec.get(),
aParam.overrideURI.spec.get()));
}
};
}
#endif // RegistryMessageUtils_h

File diff suppressed because it is too large Load Diff

View File

@ -37,10 +37,14 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsChromeRegistry_h
#define nsChromeRegistry_h
#include "nsIChromeRegistry.h"
#include "nsIToolkitChromeRegistry.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsIPrefBranch.h"
#ifdef MOZ_XUL
#include "nsIXULOverlayProvider.h"
@ -52,24 +56,19 @@
#include "nsString.h"
#include "nsTHashtable.h"
#include "nsURIHashKey.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
#include "nsInterfaceHashtable.h"
#include "nsXULAppAPI.h"
#include "nsIResProtocolHandler.h"
#include "nsIXPConnect.h"
struct PRFileDesc;
class nsIAtom;
class nsIDOMWindowInternal;
class nsILocalFile;
class nsIPrefBranch;
class nsIRDFDataSource;
class nsIRDFResource;
class nsIRDFService;
class nsISimpleEnumerator;
class nsIURL;
// The chrome registry is actually split between nsChromeRegistryChrome and
// nsChromeRegistryContent. The work/data that is common to both resides in
// the shared nsChromeRegistry implementation, with operations that only make
// sense for one side erroring out in the other.
// for component registration
// {47049e42-1d87-482a-984d-56ae185e367a}
#define NS_CHROMEREGISTRY_CID \
@ -85,49 +84,54 @@ class nsChromeRegistry : public nsIToolkitChromeRegistry,
public:
NS_DECL_ISUPPORTS
// nsIXULChromeRegistry methods:
NS_IMETHOD ReloadChrome();
NS_IMETHOD RefreshSkins();
NS_IMETHOD AllowScriptsForPackage(nsIURI* url,
PRBool* _retval NS_OUTPARAM);
NS_IMETHOD AllowContentToAccess(nsIURI* url,
PRBool* _retval NS_OUTPARAM);
// nsIChromeRegistry methods:
NS_DECL_NSICHROMEREGISTRY
NS_DECL_NSIXULCHROMEREGISTRY
NS_DECL_NSITOOLKITCHROMEREGISTRY
#ifdef MOZ_XUL
NS_DECL_NSIXULOVERLAYPROVIDER
#endif
NS_DECL_NSIOBSERVER
NS_IMETHOD_(PRBool) WrappersEnabled(nsIURI *aURI);
NS_IMETHOD ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult);
// nsChromeRegistry methods:
nsChromeRegistry() : mInitialized(PR_FALSE), mProfileLoaded(PR_FALSE) {
mPackagesHash.ops = nsnull;
}
~nsChromeRegistry();
nsChromeRegistry() : mInitialized(PR_FALSE) { }
virtual ~nsChromeRegistry();
nsresult Init();
virtual nsresult Init();
static already_AddRefed<nsIChromeRegistry> GetService();
static nsChromeRegistry* gChromeRegistry;
static nsresult Canonify(nsIURL* aChromeURL);
protected:
nsresult GetDynamicInfo(nsIURI *aChromeURL, PRBool aIsOverlay, nsISimpleEnumerator **aResult);
nsresult LoadInstallDataSource();
nsresult LoadProfileDataSource();
void FlushSkinCaches();
void FlushAllCaches();
private:
static void LogMessage(const char* aMsg, ...);
static void LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
const char* aMsg, ...);
virtual nsresult GetBaseURIFromPackage(const nsCString& aPackage,
const nsCString& aProvider,
const nsCString& aPath,
nsIURI* *aResult) = 0;
virtual nsresult GetFlagsFromPackage(const nsCString& aPackage,
PRUint32* aFlags) = 0;
nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
#ifdef MOZ_OMNIJAR
nsresult CheckOmnijarChrome();
#endif
static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow);
static nsresult GetProviderAndPath(nsIURL* aChromeURL,
nsACString& aProvider, nsACString& aPath);
public:
static already_AddRefed<nsChromeRegistry> GetSingleton();
struct ManifestProcessingContext
{
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
@ -148,139 +152,47 @@ public:
nsCOMPtr<nsIXPConnect> mXPConnect;
};
void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform, bool contentaccessible);
virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible) = 0;
public:
struct ProviderEntry
{
ProviderEntry(const nsACString& aProvider, nsIURI* aBase) :
provider(aProvider),
baseURI(aBase) { }
// Available flags
enum {
// This is a "platform" package (e.g. chrome://global-platform/).
// Appends one of win/ unix/ mac/ to the base URI.
PLATFORM_PACKAGE = 1 << 0,
nsCString provider;
nsCOMPtr<nsIURI> baseURI;
// This package should use the new XPCNativeWrappers to separate
// content from chrome. This flag is currently unused (because we call
// into xpconnect at registration time).
XPCNATIVEWRAPPERS = 1 << 1,
// Content script may access files in this package
CONTENT_ACCESSIBLE = 1 << 2
};
class nsProviderArray
{
public:
nsProviderArray() :
mArray(1) { }
~nsProviderArray()
{ Clear(); }
// When looking up locales and skins, the "selected" locale is not always
// available. This enum identifies what kind of match is desired/found.
enum MatchType {
EXACT = 0,
LOCALE = 1, // "en-GB" is selected, we found "en-US"
ANY = 2
};
nsIURI* GetBase(const nsACString& aPreferred, MatchType aType);
const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
void SetBase(const nsACString& aProvider, nsIURI* base);
void EnumerateToArray(nsTArray<nsCString> *a);
void Clear();
private:
ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
nsVoidArray mArray;
};
struct PackageEntry : public PLDHashEntryHdr
{
PackageEntry(const nsACString& package);
~PackageEntry() { }
// Available flags
enum {
// This is a "platform" package (e.g. chrome://global-platform/).
// Appends one of win/ unix/ mac/ to the base URI.
PLATFORM_PACKAGE = 1 << 0,
// Content script may access files in this package
CONTENT_ACCESSIBLE = 1 << 1
};
nsCString package;
nsCOMPtr<nsIURI> baseURI;
PRUint32 flags;
nsProviderArray locales;
nsProviderArray skins;
};
private:
static PLDHashNumber HashKey(PLDHashTable *table, const void *key);
static PRBool MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
const void *key);
static void ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry);
static PRBool InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key);
static const PLDHashTableOps kTableOps;
public:
class OverlayListEntry : public nsURIHashKey
{
public:
typedef nsURIHashKey::KeyType KeyType;
typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
OverlayListEntry(OverlayListEntry& toCopy) : nsURIHashKey(toCopy),
mArray(toCopy.mArray) { }
~OverlayListEntry() { }
void AddURI(nsIURI* aURI);
nsCOMArray<nsIURI> mArray;
};
class OverlayListHash
{
public:
OverlayListHash() { }
~OverlayListHash() { }
PRBool Init() { return mTable.Init(); }
void Add(nsIURI* aBase, nsIURI* aOverlay);
void Clear() { mTable.Clear(); }
const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
private:
nsTHashtable<OverlayListEntry> mTable;
};
private:
PRBool mInitialized;
PRBool mProfileLoaded;
// Hash of package names ("global") to PackageEntry objects
PLDHashTable mPackagesHash;
// Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
// to a list of overlays/stylesheets
OverlayListHash mOverlayHash;
OverlayListHash mStyleHash;
// "Override" table (chrome URI string -> real URI)
nsInterfaceHashtable<nsURIHashKey, nsIURI> mOverrideTable;
nsCString mSelectedLocale;
nsCString mSelectedSkin;
};
#endif // nsChromeRegistry_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,223 @@
/* -*- Mode: C++; tab-width: 8; 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) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net> (Initial Developer)
*
* 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 ***** */
#ifndef nsChromeRegistryChrome_h
#define nsChromeRegistryChrome_h
#include "nsChromeRegistry.h"
namespace mozilla {
namespace dom {
class PContentProcessParent;
}
}
class nsIPrefBranch;
class nsChromeRegistryChrome : public nsChromeRegistry
{
public:
nsChromeRegistryChrome();
~nsChromeRegistryChrome();
NS_OVERRIDE nsresult Init();
NS_OVERRIDE NS_IMETHOD CheckForNewChrome();
NS_OVERRIDE NS_IMETHOD CheckForOSAccessibility();
NS_OVERRIDE NS_IMETHOD GetLocalesForPackage(const nsACString& aPackage,
nsIUTF8StringEnumerator* *aResult);
NS_OVERRIDE NS_IMETHOD IsLocaleRTL(const nsACString& package,
PRBool *aResult);
NS_OVERRIDE NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
nsACString& aLocale);
NS_OVERRIDE NS_IMETHOD Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *someData);
#ifdef MOZ_XUL
NS_OVERRIDE NS_IMETHOD GetXULOverlays(nsIURI *aURI,
nsISimpleEnumerator **_retval);
NS_OVERRIDE NS_IMETHOD GetStyleOverlays(nsIURI *aURI,
nsISimpleEnumerator **_retval);
#endif
#ifdef MOZ_IPC
void SendRegisteredChrome(mozilla::dom::PContentProcessParent* aChild);
#endif
private:
#ifdef MOZ_IPC
static PLDHashOperator CollectPackages(PLDHashTable *table,
PLDHashEntryHdr *entry,
PRUint32 number, void *arg);
#endif
nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
NS_OVERRIDE nsresult GetBaseURIFromPackage(const nsCString& aPackage,
const nsCString& aProvider,
const nsCString& aPath,
nsIURI* *aResult);
NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage,
PRUint32* aFlags);
static const PLDHashTableOps kTableOps;
static PLDHashNumber HashKey(PLDHashTable *table, const void *key);
static PRBool MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
const void *key);
static void ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry);
static PRBool InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key);
struct ProviderEntry
{
ProviderEntry(const nsACString& aProvider, nsIURI* aBase) :
provider(aProvider),
baseURI(aBase) { }
nsCString provider;
nsCOMPtr<nsIURI> baseURI;
};
class nsProviderArray
{
public:
nsProviderArray() :
mArray(1) { }
~nsProviderArray()
{ Clear(); }
// When looking up locales and skins, the "selected" locale is not always
// available. This enum identifies what kind of match is desired/found.
enum MatchType {
EXACT = 0,
LOCALE = 1, // "en-GB" is selected, we found "en-US"
ANY = 2
};
nsIURI* GetBase(const nsACString& aPreferred, MatchType aType);
const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
void SetBase(const nsACString& aProvider, nsIURI* base);
void EnumerateToArray(nsTArray<nsCString> *a);
void Clear();
private:
ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
nsVoidArray mArray;
};
struct PackageEntry : public PLDHashEntryHdr
{
PackageEntry(const nsACString& package)
: package(package), flags(0) { }
~PackageEntry() { }
nsCString package;
nsCOMPtr<nsIURI> baseURI;
PRUint32 flags;
nsProviderArray locales;
nsProviderArray skins;
};
class OverlayListEntry : public nsURIHashKey
{
public:
typedef nsURIHashKey::KeyType KeyType;
typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
OverlayListEntry(OverlayListEntry& toCopy) : nsURIHashKey(toCopy),
mArray(toCopy.mArray) { }
~OverlayListEntry() { }
void AddURI(nsIURI* aURI);
nsCOMArray<nsIURI> mArray;
};
class OverlayListHash
{
public:
OverlayListHash() { }
~OverlayListHash() { }
PRBool Init() { return mTable.Init(); }
void Add(nsIURI* aBase, nsIURI* aOverlay);
void Clear() { mTable.Clear(); }
const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
private:
nsTHashtable<OverlayListEntry> mTable;
};
// Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
// to a list of overlays/stylesheets
OverlayListHash mOverlayHash;
OverlayListHash mStyleHash;
PRBool mProfileLoaded;
nsCString mSelectedLocale;
nsCString mSelectedSkin;
// Hash of package names ("global") to PackageEntry objects
PLDHashTable mPackagesHash;
virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
};
#endif // nsChromeRegistryChrome_h

View File

@ -0,0 +1,331 @@
/* -*- Mode: C++; tab-width: 8; 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) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net> (Initial Developer)
*
* 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 ***** */
#include "RegistryMessageUtils.h"
#include "nsChromeRegistry.h"
#include "nsChromeRegistryContent.h"
#include "nsString.h"
#include "nsNetUtil.h"
#include "nsResProtocolHandler.h"
nsChromeRegistryContent::nsChromeRegistryContent()
{
mPackagesHash.Init();
}
void
nsChromeRegistryContent::RegisterRemoteChrome(
const nsTArray<ChromePackage>& aPackages,
const nsTArray<ResourceMapping>& aResources,
const nsTArray<OverrideMapping>& aOverrides)
{
for (PRUint32 i = aPackages.Length(); i > 0; ) {
--i;
RegisterPackage(aPackages[i]);
}
for (PRUint32 i = aResources.Length(); i > 0; ) {
--i;
RegisterResource(aResources[i]);
}
for (PRUint32 i = aOverrides.Length(); i > 0; ) {
--i;
RegisterOverride(aOverrides[i]);
}
}
void
nsChromeRegistryContent::RegisterPackage(const ChromePackage& aPackage)
{
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io)
return;
nsCOMPtr<nsIURI> content, locale, skin;
if (aPackage.contentBaseURI.spec.Length()) {
nsresult rv = NS_NewURI(getter_AddRefs(content),
aPackage.contentBaseURI.spec,
aPackage.contentBaseURI.charset.get(),
nsnull, io);
if (NS_FAILED(rv))
return;
}
if (aPackage.localeBaseURI.spec.Length()) {
nsresult rv = NS_NewURI(getter_AddRefs(locale),
aPackage.localeBaseURI.spec,
aPackage.localeBaseURI.charset.get(),
nsnull, io);
if (NS_FAILED(rv))
return;
}
if (aPackage.skinBaseURI.spec.Length()) {
nsCOMPtr<nsIURI> skinBaseURI;
nsresult rv = NS_NewURI(getter_AddRefs(skin),
aPackage.skinBaseURI.spec,
aPackage.skinBaseURI.charset.get(),
nsnull, io);
if (NS_FAILED(rv))
return;
}
PackageEntry* entry = new PackageEntry;
entry->flags = aPackage.flags;
entry->contentBaseURI = content;
entry->localeBaseURI = locale;
entry->skinBaseURI = skin;
nsresult rv = mPackagesHash.Put(aPackage.package, entry);
if (NS_FAILED(rv))
return;
}
void
nsChromeRegistryContent::RegisterResource(const ResourceMapping& aResource)
{
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io)
return;
nsCOMPtr<nsIProtocolHandler> ph;
nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIResProtocolHandler> rph (do_QueryInterface(ph));
if (!rph)
return;
nsCOMPtr<nsIURI> resolvedURI;
if (aResource.resolvedURI.spec.Length()) {
nsresult rv = NS_NewURI(getter_AddRefs(resolvedURI),
aResource.resolvedURI.spec,
aResource.resolvedURI.charset.get(),
nsnull, io);
if (NS_FAILED(rv))
return;
}
rv = rph->SetSubstitution(aResource.resource, resolvedURI);
if (NS_FAILED(rv))
return;
}
void
nsChromeRegistryContent::RegisterOverride(const OverrideMapping& aOverride)
{
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io)
return;
nsCOMPtr<nsIURI> chromeURI, overrideURI;
nsresult rv = NS_NewURI(getter_AddRefs(chromeURI),
aOverride.originalURI.spec,
aOverride.originalURI.charset.get(),
nsnull, io);
if (NS_FAILED(rv))
return;
rv = NS_NewURI(getter_AddRefs(overrideURI), aOverride.overrideURI.spec,
aOverride.overrideURI.charset.get(), nsnull, io);
if (NS_FAILED(rv))
return;
mOverrideTable.Put(chromeURI, overrideURI);
}
nsresult
nsChromeRegistryContent::GetBaseURIFromPackage(const nsCString& aPackage,
const nsCString& aProvider,
const nsCString& aPath,
nsIURI* *aResult)
{
PackageEntry* entry;
if (!mPackagesHash.Get(aPackage, &entry)) {
return NS_ERROR_FAILURE;
}
*aResult = nsnull;
if (aProvider.EqualsLiteral("locale")) {
*aResult = entry->localeBaseURI;
}
else if (aProvider.EqualsLiteral("skin")) {
*aResult = entry->skinBaseURI;
}
else if (aProvider.EqualsLiteral("content")) {
*aResult = entry->contentBaseURI;
}
return NS_OK;
}
nsresult
nsChromeRegistryContent::GetFlagsFromPackage(const nsCString& aPackage,
PRUint32* aFlags)
{
PackageEntry* entry;
if (!mPackagesHash.Get(aPackage, &entry)) {
return NS_ERROR_FAILURE;
}
*aFlags = entry->flags;
return NS_OK;
}
// All functions following only make sense in chrome, and therefore assert
#define CONTENT_NOTREACHED() \
NS_NOTREACHED("Content should not be calling this")
#define CONTENT_NOT_IMPLEMENTED() \
CONTENT_NOTREACHED(); \
return NS_ERROR_NOT_IMPLEMENTED;
NS_IMETHODIMP
nsChromeRegistryContent::GetLocalesForPackage(const nsACString& aPackage,
nsIUTF8StringEnumerator* *aResult)
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::CheckForOSAccessibility()
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::CheckForNewChrome()
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::IsLocaleRTL(const nsACString& package,
PRBool *aResult)
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::GetSelectedLocale(const nsACString& aPackage,
nsACString& aLocale)
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::GetStyleOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult)
{
CONTENT_NOT_IMPLEMENTED();
}
NS_IMETHODIMP
nsChromeRegistryContent::GetXULOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult)
{
CONTENT_NOT_IMPLEMENTED();
}
void
nsChromeRegistryContent::ManifestContent(ManifestProcessingContext& cx,
int lineno, char *const * argv,
bool platform, bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestLocale(ManifestProcessingContext& cx,
int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestSkin(ManifestProcessingContext& cx,
int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestStyle(ManifestProcessingContext& cx,
int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestOverride(ManifestProcessingContext& cx,
int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}
void
nsChromeRegistryContent::ManifestResource(ManifestProcessingContext& cx,
int lineno,
char *const * argv, bool platform,
bool contentaccessible)
{
CONTENT_NOTREACHED();
}

View File

@ -0,0 +1,122 @@
/* -*- Mode: C++; tab-width: 8; 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) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net> (Initial Developer)
*
* 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 ***** */
#ifndef nsChromeRegistryContent_h
#define nsChromeRegistryContent_h
#include "nsChromeRegistry.h"
#include "nsTArray.h"
#include "nsClassHashtable.h"
class nsCString;
struct ChromePackage;
struct ResourceMapping;
struct OverrideMapping;
class nsChromeRegistryContent : public nsChromeRegistry
{
public:
nsChromeRegistryContent();
void RegisterRemoteChrome(const nsTArray<ChromePackage>& aPackages,
const nsTArray<ResourceMapping>& aResources,
const nsTArray<OverrideMapping>& aOverrides);
NS_OVERRIDE NS_IMETHOD GetLocalesForPackage(const nsACString& aPackage,
nsIUTF8StringEnumerator* *aResult);
NS_OVERRIDE NS_IMETHOD CheckForNewChrome();
NS_OVERRIDE NS_IMETHOD CheckForOSAccessibility();
NS_OVERRIDE NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData);
NS_OVERRIDE NS_IMETHOD IsLocaleRTL(const nsACString& package,
PRBool *aResult);
NS_OVERRIDE NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
nsACString& aLocale);
NS_OVERRIDE NS_IMETHOD GetStyleOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult);
NS_OVERRIDE NS_IMETHOD GetXULOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult);
private:
struct PackageEntry
{
PackageEntry() : flags(0) { }
~PackageEntry() { }
nsCOMPtr<nsIURI> contentBaseURI;
nsCOMPtr<nsIURI> localeBaseURI;
nsCOMPtr<nsIURI> skinBaseURI;
PRUint32 flags;
};
void RegisterPackage(const ChromePackage& aPackage);
void RegisterResource(const ResourceMapping& aResource);
void RegisterOverride(const OverrideMapping& aOverride);
NS_OVERRIDE nsresult GetBaseURIFromPackage(const nsCString& aPackage,
const nsCString& aProvider,
const nsCString& aPath,
nsIURI* *aResult);
NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage, PRUint32* aFlags);
nsClassHashtable<nsCStringHashKey, PackageEntry> mPackagesHash;
virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
};
#endif // nsChromeRegistryContent_h

View File

@ -46,5 +46,11 @@ MODULE = test_chrome
XPCSHELL_TESTS = unit \
$(NULL)
ifdef MOZ_IPC
# FIXME/bug 575918: out-of-process xpcshell is broken on OS X
ifneq ($(OS_ARCH),Darwin)
XPCSHELL_TESTS += unit_ipc
endif
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,5 @@
resource foo resource://foo/foo-resource/
content foo resource://foo/foo-content/
locale foo foo resource://foo/foo-locale/
skin foo foo resource://foo/foo-skin/
override chrome://good-package/content/override-me.xul resource://foo/foo-override/override-me.xul

View File

@ -0,0 +1,122 @@
/* -*- Mode: C++; tab-width: 8; 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 Chrome Registration Test Code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net> (Original Author)
*
* 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 ***** */
// head_crtestutils.js doesn't get included in the child by default
if (typeof registerManifests === "undefined") {
load("../unit/head_crtestutils.js");
}
let manifests = [
do_get_file("../unit/data/test_resolve_uris.manifest"),
];
registerManifests(manifests);
function do_run_test()
{
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIChromeRegistry);
var runtime = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULRuntime);
if (runtime.processType ==
Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
cr.checkForNewChrome();
}
// See if our various things were able to register
let registrationTypes = [
"content",
"locale",
"skin",
"override",
"resource",
];
for (let j = 0; j < registrationTypes.length; j++) {
let type = registrationTypes[j];
dump("Testing type '" + type + "'\n");
let expectedURI = "resource://foo/foo-" + type + "/";
let sourceURI = "chrome://foo/" + type + "/";
switch (type) {
case "content":
expectedURI += "foo.xul";
break;
case "locale":
expectedURI += "foo.dtd";
break;
case "skin":
expectedURI += "foo.css";
break;
case "override":
sourceURI = "chrome://good-package/content/override-me.xul";
expectedURI += "override-me.xul";
break;
case "resource":
sourceURI = "resource://foo/";
break;
};
try {
let ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
sourceURI = ios.newURI(sourceURI, null, null);
let uri;
if (type == "resource") {
// resources go about a slightly different way than everything else
let rph = ios.getProtocolHandler("resource").
QueryInterface(Ci.nsIResProtocolHandler);
uri = rph.resolveURI(sourceURI);
}
else {
uri = cr.convertChromeURL(sourceURI).spec;
}
do_check_eq(expectedURI, uri);
}
catch (e) {
dump(e + "\n");
do_throw("Should have registered a handler for type '" +
type + "'\n");
}
}
}
if (typeof run_test === "undefined") {
run_test = function() {
do_run_test();
};
}

View File

@ -0,0 +1,9 @@
//
// Run test script in content process instead of chrome (xpcshell's default)
//
function run_test() {
load("../unit/test_resolve_uris.js");
do_run_test();
run_test_in_child("../unit/test_resolve_uris.js");
}

View File

@ -4985,7 +4985,6 @@ case "${target}" in
MOZ_CRASHREPORTER=
NS_PRINTING=
NECKO_WIFI=
MOZ_PLUGINS=
MOZ_THUMB2=1
MOZ_THEME_FASTSTRIPE=1
MOZ_TREE_FREETYPE=1
@ -5700,7 +5699,7 @@ dnl ========================================================
dnl = Disable IPC support for tabs and plugins
dnl ========================================================
case "${target}" in
*-wince*|*-android*)
*-wince*)
MOZ_IPC=
;;
esac

View File

@ -41,9 +41,12 @@
interface nsIDocShell;
interface nsIURI;
interface nsIWebProgress;
interface nsIFrame;
interface nsIChromeFrameMessageManager;
interface nsIVariant;
[scriptable, uuid(3b256c12-20e1-4fd3-8edb-b9c793919f15)]
[scriptable, uuid(65d2c9e2-852c-48cf-a95d-9b82f1273c15)]
interface nsIFrameLoader : nsISupports
{
/**
@ -51,6 +54,11 @@ interface nsIFrameLoader : nsISupports
*/
readonly attribute nsIDocShell docShell;
/**
* Get the nsIWebProgress from the frame loader, allowing listener registration.
*/
readonly attribute nsIWebProgress webProgress;
/**
* Start loading the frame. This method figures out what to load
* from the owner content in the frame loader.
@ -76,13 +84,54 @@ interface nsIFrameLoader : nsISupports
*/
readonly attribute boolean depthTooGreat;
/**
* Updates the position and size of the subdocument loaded by this frameloader.
*
* @param aIFrame The nsIFrame for the content node that owns this frameloader
*/
[noscript] void updatePositionAndSize(in nsIFrame aIFrame);
/**
* Activate remote frame.
* Throws an exception with non-remote frames.
*/
void activateRemoteFrame();
/**
* @see nsIDOMWindowUtils sendMouseEvent.
*/
void sendCrossProcessMouseEvent(in AString aType,
in float aX,
in float aY,
in long aButton,
in long aClickCount,
in long aModifiers,
[optional] in boolean aIgnoreRootScrollFrame);
/**
* Activate event forwarding from client (remote frame) to parent.
*/
void activateFrameEvent(in AString aType, in boolean capture);
// Note, when frameloaders are swapped, also messageManagers are swapped.
readonly attribute nsIChromeFrameMessageManager messageManager;
/**
* @see nsIDOMWindowUtils sendKeyEvent.
*/
void sendCrossProcessKeyEvent(in AString aType,
in long aKeyCode,
in long aCharCode,
in long aModifiers,
[optional] in boolean aPreventDefault);
attribute boolean delayRemoteDialogs;
};
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
[scriptable, uuid(8f3b12a0-35ae-4e0d-9152-8e0d7e49d446)]
[scriptable, uuid(5879040e-83e9-40e3-b2bb-5ddf43b76e47)]
interface nsIFrameLoaderOwner : nsISupports
{
/**

View File

@ -52,7 +52,7 @@ interface nsIFrameMessageListener : nsISupports
* name: %message name%,
* sync: %true or false%.
* json: %json object or null%,
* objects: %array of cpow or null, always null if sync is false%
* objects: %array of handles or null, always null if sync is false%
* }
* @note objects property isn't implemented yet.
*

View File

@ -169,6 +169,8 @@ EXTRA_JS_MODULES = \
CSPUtils.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
INCLUDES += \
@ -184,8 +186,11 @@ INCLUDES += \
-I$(srcdir)/../../../dom/base \
-I$(srcdir)/../../xml/document/src \
-I$(topsrcdir)/xpcom/io \
-I$(topsrcdir)/dom/ipc \
-I$(topsrcdir)/js/src/xpconnect/src \
-I$(topsrcdir)/caps/include \
$(NULL)
CXXFLAGS += $(TK_CFLAGS)
DEFINES += -D_IMPL_NS_LAYOUT

View File

@ -89,6 +89,7 @@
#include "nsNodeUtils.h"
#include "nsLayoutUtils.h" // for GetFrameForPoint
#include "nsIFrame.h"
#include "nsITabChild.h"
#include "nsRange.h"
#include "nsIDOMText.h"
@ -1084,7 +1085,8 @@ nsExternalResourceMap::LoadgroupCallbacks::GetInterface(const nsIID & aIID,
void **aSink)
{
if (mCallbacks &&
(IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || IID_IS(nsIAuthPrompt2))) {
(IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || IID_IS(nsIAuthPrompt2) ||
IID_IS(nsITabChild))) {
return mCallbacks->GetInterface(aIID, aSink);
}

View File

@ -23,6 +23,7 @@
* Contributor(s):
* Johnny Stenback <jst@netscape.com> (original author)
* Boris Zbarsky <bzbarsky@mit.edu>
* Frederic Plourde <frederic.plourde@polymtl.ca>
*
* 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"),
@ -43,6 +44,18 @@
* handling of loads in it, recursion-checking).
*/
#ifdef MOZ_WIDGET_QT
#include <QtGui/QX11EmbedWidget>
#include <QGraphicsWidget>
#include <QGraphicsProxyWidget>
#endif
#ifdef MOZ_IPC
# include "base/basictypes.h"
#endif
#include "prenv.h"
#include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMWindow.h"
@ -54,6 +67,7 @@
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsIWebNavigation.h"
#include "nsIWebProgress.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeNode.h"
@ -61,6 +75,8 @@
#include "nsIDocShellLoadInfo.h"
#include "nsIBaseWindow.h"
#include "nsContentUtils.h"
#include "nsIXPConnect.h"
#include "nsIJSContextStack.h"
#include "nsUnicharUtils.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h"
@ -75,6 +91,8 @@
#include "nsISHistory.h"
#include "nsISHistoryInternal.h"
#include "nsIDOMNSHTMLDocument.h"
#include "nsLayoutUtils.h"
#include "nsIView.h"
#include "nsPLDOMEvent.h"
@ -87,10 +105,29 @@
#include "nsThreadUtils.h"
#include "nsIContentViewer.h"
#include "nsIView.h"
#include "nsIDOMChromeWindow.h"
#include "nsInProcessTabChildGlobal.h"
#include "mozilla/AutoRestore.h"
#ifdef MOZ_WIDGET_GTK2
#include "mozcontainer.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#endif
#ifdef MOZ_IPC
#include "ContentProcessParent.h"
#include "TabParent.h"
using namespace mozilla;
using namespace mozilla::dom;
#endif
#include "jsapi.h"
class nsAsyncDocShellDestroyer : public nsRunnable
{
public:
@ -257,11 +294,34 @@ nsresult
nsFrameLoader::ReallyStartLoadingInternal()
{
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
// Just to be safe, recheck uri.
nsresult rv = CheckURILoad(mURIToLoad);
NS_ENSURE_SUCCESS(rv, rv);
rv = EnsureDocShell();
nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return rv;
}
#ifdef MOZ_IPC
if (mRemoteFrame) {
if (!mChildProcess) {
TryNewProcess();
}
if (!mChildProcess) {
NS_WARNING("Couldn't create child process for iframe.");
return NS_ERROR_FAILURE;
}
// FIXME get error codes from child
mChildProcess->LoadURL(mURIToLoad);
return NS_OK;
}
#endif
NS_ASSERTION(mDocShell,
"MaybeCreateDocShell succeeded with a null mDocShell");
// Just to be safe, recheck uri.
rv = CheckURILoad(mURIToLoad);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
@ -322,6 +382,15 @@ nsFrameLoader::CheckURILoad(nsIURI* aURI)
}
// Bail out if this is an infinite recursion scenario
rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return rv;
}
#ifdef MOZ_IPC
if (mRemoteFrame) {
return NS_OK;
}
#endif
return CheckForRecursiveLoad(aURI);
}
@ -334,8 +403,17 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
// that. If not, we're most likely in the middle of being torn down,
// then we just return null.
if (mOwnerContent) {
nsresult rv = EnsureDocShell();
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv))
return rv;
#ifdef MOZ_IPC
if (mRemoteFrame) {
NS_WARNING("No docshells for remote frames!");
return NS_ERROR_NOT_AVAILABLE;
}
#endif
NS_ASSERTION(mDocShell,
"MaybeCreateDocShell succeeded, but null mDocShell");
}
*aDocShell = mDocShell;
@ -344,6 +422,34 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::GetWebProgress(nsIWebProgress **aWebProgress)
{
nsresult rv;
*aWebProgress = nsnull;
#ifdef MOZ_IPC
if (mRemoteFrame) {
if (!mChildProcess) {
TryNewProcess();
}
if (!mChildProcess) {
return NS_ERROR_UNEXPECTED;
}
*aWebProgress = mChildProcess;
NS_ADDREF(*aWebProgress);
return NS_OK;
}
#endif
nsCOMPtr<nsIDocShell> shell;
rv = GetDocShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(shell));
progress.swap(*aWebProgress);
}
return rv;
}
void
nsFrameLoader::Finalize()
{
@ -547,50 +653,63 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
nsContentType contentType;
nsresult rv = EnsureDocShell();
nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return PR_FALSE;
}
if (!mDocShell)
return PR_FALSE;
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell)
return PR_TRUE;
mDocShell->SetMarginWidth(marginWidth);
mDocShell->SetMarginHeight(marginHeight);
nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
if (sc) {
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
scrollbarPrefX);
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
scrollbarPrefY);
}
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
NS_ASSERTION(treeItem,
"Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
PRInt32 itemType;
treeItem->GetItemType(&itemType);
if (itemType == nsIDocShellTreeItem::typeChrome)
#ifdef MOZ_IPC
if (mRemoteFrame) {
contentType = eContentTypeUI;
else {
nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
}
else
#endif
{
if (!mDocShell)
return false;
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell)
return true;
mDocShell->SetMarginWidth(marginWidth);
mDocShell->SetMarginHeight(marginHeight);
nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
if (sc) {
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
scrollbarPrefX);
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
scrollbarPrefY);
}
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
NS_ASSERTION(treeItem,
"Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
PRInt32 itemType;
treeItem->GetItemType(&itemType);
if (itemType == nsIDocShellTreeItem::typeChrome)
contentType = eContentTypeUI;
else {
nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
}
}
nsIView* view = frame->CreateViewAndWidget(contentType);
if (!view)
return PR_FALSE;
#ifdef MOZ_IPC
if (mRemoteFrame) {
return ShowRemoteFrame(frame, view);
}
#endif
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
@ -604,6 +723,7 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
// sub-document. This shouldn't be necessary, but given the way our
// editor works, it is. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=284245
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsIDOMNSHTMLDocument> doc =
@ -629,6 +749,94 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
return PR_TRUE;
}
#ifdef MOZ_IPC
bool
nsFrameLoader::ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view)
{
NS_ASSERTION(mRemoteFrame, "ShowRemote only makes sense on remote frames.");
if (!mChildProcess) {
TryNewProcess();
}
if (!mChildProcess) {
NS_ERROR("Couldn't create child process.");
return false;
}
nsIWidget* w = view->GetWidget();
if (!w) {
NS_ERROR("Our view doesn't have a widget. Totally stuffed!");
return false;
}
nsIntSize size = GetSubDocumentSize(frame->GetFrame());
#ifdef XP_WIN
HWND parentwin =
static_cast<HWND>(w->GetNativeData(NS_NATIVE_WINDOW));
mChildProcess->SendcreateWidget(parentwin);
#elif defined(MOZ_WIDGET_GTK2)
GdkWindow* parent_win =
static_cast<GdkWindow*>(w->GetNativeData(NS_NATIVE_WINDOW));
gpointer user_data = nsnull;
gdk_window_get_user_data(parent_win, &user_data);
MozContainer* parentMozContainer = MOZ_CONTAINER(user_data);
GtkContainer* container = GTK_CONTAINER(parentMozContainer);
// create the socket for the child and add it to our view's widget
mRemoteSocket = gtk_socket_new();
gtk_widget_set_parent_window(mRemoteSocket, parent_win);
gtk_container_add(container, mRemoteSocket);
gtk_widget_realize(mRemoteSocket);
// set the child window's size and position
GtkAllocation alloc = { 0, 0, size.width, size.height };
gtk_widget_size_allocate(mRemoteSocket, &alloc);
gtk_widget_show(mRemoteSocket);
GdkNativeWindow id = gtk_socket_get_id(GTK_SOCKET(mRemoteSocket));
mChildProcess->SendcreateWidget(id);
#elif defined(MOZ_WIDGET_QT)
if (getenv("USE_XEMBED_PROXY")) {
// Very bad idea to use Xembedding for IPC, but test-ipc.xul still rendering with XEmbed
QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(w->GetNativeData(NS_NATIVE_WINDOW));
NS_ENSURE_TRUE(widget, false);
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(widget);
NS_ENSURE_TRUE(proxy, false);
mRemoteSocket = new QX11EmbedContainer();
NS_ENSURE_TRUE(mRemoteSocket, false);
proxy->setWidget(mRemoteSocket);
mRemoteSocket->show();
mRemoteSocket->resize(size.width, size.height);
mChildProcess->SendcreateWidget(0);
} else {
// Don't create any parent/child XEmbed, because we are painting with shared memory
mChildProcess->SendcreateWidget(0);
}
#elif defined(ANDROID)
// Painting with shared memory
mChildProcess->SendcreateWidget(0);
#elif defined(XP_MACOSX)
# warning IMPLEMENT ME
#else
#error TODO for this platform
#endif
mChildProcess->Move(0, 0, size.width, size.height);
mRemoteWidgetCreated = PR_TRUE;
nsCOMPtr<nsIChromeFrameMessageManager> dummy;
GetMessageManager(getter_AddRefs(dummy)); // Initialize message manager.
return true;
}
#endif
void
nsFrameLoader::Hide()
{
@ -949,6 +1157,18 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
return NS_OK;
}
void
nsFrameLoader::DestroyChild()
{
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SetOwnerElement(nsnull);
PIFrameEmbeddingParent::Send__delete__(mChildProcess);
mChildProcess = nsnull;
}
#endif
}
NS_IMETHODIMP
nsFrameLoader::Destroy()
{
@ -974,7 +1194,8 @@ nsFrameLoader::Destroy()
mOwnerContent = nsnull;
}
DestroyChild();
// Let the tree owner know we're gone.
if (mIsTopLevelContent) {
nsCOMPtr<nsIDocShellTreeItem> ourItem = do_QueryInterface(mDocShell);
@ -1018,14 +1239,64 @@ nsFrameLoader::GetDepthTooGreat(PRBool* aDepthTooGreat)
return NS_OK;
}
#ifdef MOZ_IPC
bool
nsFrameLoader::ShouldUseRemoteProcess()
{
// Check for *disabled* multi-process first: environment, prefs, attribute
// Then check for *enabled* multi-process pref: attribute, prefs
// Default is not-remote.
if (PR_GetEnv("MOZ_DISABLE_OOP_TABS")) {
return false;
}
PRBool remoteDisabled = nsContentUtils::GetBoolPref("dom.ipc.tabs.disabled",
PR_FALSE);
if (remoteDisabled) {
return false;
}
static nsIAtom* const *const remoteValues[] = {
&nsGkAtoms::_false,
&nsGkAtoms::_true,
nsnull
};
switch (mOwnerContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::Remote,
remoteValues, eCaseMatters)) {
case 0:
return false;
case 1:
return true;
}
PRBool remoteEnabled = nsContentUtils::GetBoolPref("dom.ipc.tabs.enabled",
PR_FALSE);
return (bool) remoteEnabled;
}
#endif
nsresult
nsFrameLoader::EnsureDocShell()
nsFrameLoader::MaybeCreateDocShell()
{
if (mDocShell) {
return NS_OK;
}
#ifdef MOZ_IPC
if (mRemoteFrame) {
return NS_OK;
}
#endif
NS_ENSURE_STATE(!mDestroyCalled);
#ifdef MOZ_IPC
if (ShouldUseRemoteProcess()) {
mRemoteFrame = true;
return NS_OK;
}
#endif
// Get our parent docshell off the document of mOwnerContent
// XXXbz this is such a total hack.... We really need to have a
// better setup for doing this.
@ -1158,9 +1429,20 @@ nsFrameLoader::GetURL(nsString& aURI)
nsresult
nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
{
nsresult rv;
mDepthTooGreat = PR_FALSE;
nsresult rv = EnsureDocShell();
NS_ENSURE_SUCCESS(rv, rv);
rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return rv;
}
#ifdef MOZ_IPC
NS_ASSERTION(!mRemoteFrame,
"Shouldn't call CheckForRecursiveLoad on remote frames.");
#endif
if (!mDocShell) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
NS_ASSERTION(treeItem, "docshell must be a treeitem!");
@ -1246,11 +1528,245 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::UpdatePositionAndSize(nsIFrame *aIFrame)
{
#ifdef MOZ_IPC
if (mRemoteFrame) {
if (mChildProcess) {
nsIntSize size = GetSubDocumentSize(aIFrame);
#ifdef MOZ_WIDGET_GTK2
if (mRemoteSocket) {
GtkAllocation alloc = {0, 0, size.width, size.height };
gtk_widget_size_allocate(mRemoteSocket, &alloc);
}
#elif defined(MOZ_WIDGET_QT)
if (mRemoteSocket)
mRemoteSocket->resize(size.width, size.height);
#endif
mChildProcess->Move(0, 0, size.width, size.height);
}
return NS_OK;
}
#endif
return UpdateBaseWindowPositionAndSize(aIFrame);
}
nsresult
nsFrameLoader::UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame)
{
nsCOMPtr<nsIDocShell> docShell;
GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
// resize the sub document
if (baseWindow) {
PRInt32 x = 0;
PRInt32 y = 0;
nsWeakFrame weakFrame(aIFrame);
baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull);
if (!weakFrame.IsAlive()) {
// GetPositionAndSize() killed us
return NS_OK;
}
nsIntSize size = GetSubDocumentSize(aIFrame);
baseWindow->SetPositionAndSize(x, y, size.width, size.height, PR_FALSE);
}
return NS_OK;
}
nsIntSize
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
{
nsSize docSizeAppUnits;
nsPresContext* presContext = aIFrame->PresContext();
nsCOMPtr<nsIDOMHTMLFrameElement> frameElem =
do_QueryInterface(aIFrame->GetContent());
if (frameElem) {
docSizeAppUnits = aIFrame->GetSize();
} else {
docSizeAppUnits = aIFrame->GetContentRect().Size();
}
return nsIntSize(presContext->AppUnitsToDevPixels(docSizeAppUnits.width),
presContext->AppUnitsToDevPixels(docSizeAppUnits.height));
}
#ifdef MOZ_IPC
bool
nsFrameLoader::TryNewProcess()
{
NS_ASSERTION(!mChildProcess, "TryNewProcess called with a process already?");
nsIDocument* doc = mOwnerContent->GetDocument();
if (!doc) {
return false;
}
if (doc->GetDisplayDocument()) {
// Don't allow subframe loads in external reference documents
return false;
}
nsCOMPtr<nsIWebNavigation> parentAsWebNav =
do_GetInterface(doc->GetScriptGlobalObject());
if (!parentAsWebNav) {
return false;
}
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
PRInt32 parentType;
parentAsItem->GetItemType(&parentType);
if (parentType != nsIDocShellTreeItem::typeChrome) {
return false;
}
if (!mOwnerContent->IsXUL()) {
return false;
}
nsAutoString value;
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
if (!value.LowerCaseEqualsLiteral("content") &&
!StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator())) {
return false;
}
ContentProcessParent* parent = ContentProcessParent::GetSingleton();
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
mChildProcess = parent->CreateTab();
if (mChildProcess) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mChildProcess->SetOwnerElement(element);
nsCOMPtr<nsIDocShellTreeItem> rootItem;
parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
NS_ABORT_IF_FALSE(rootChromeWin, "How did we not get a chrome window here?");
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
mChildProcess->SetBrowserDOMWindow(browserDOMWin);
mChildHost = parent;
}
return true;
}
#endif
#ifdef MOZ_IPC
mozilla::dom::PIFrameEmbeddingParent*
nsFrameLoader::GetChildProcess()
{
return mChildProcess;
}
#endif
NS_IMETHODIMP
nsFrameLoader::ActivateRemoteFrame() {
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->Activate();
return NS_OK;
}
#endif
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
float aX,
float aY,
PRInt32 aButton,
PRInt32 aClickCount,
PRInt32 aModifiers,
PRBool aIgnoreRootScrollFrame)
{
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SendMouseEvent(aType, aX, aY, aButton,
aClickCount, aModifiers,
aIgnoreRootScrollFrame);
return NS_OK;
}
#endif
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsFrameLoader::ActivateFrameEvent(const nsAString& aType,
PRBool aCapture)
{
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SendactivateFrameEvent(nsString(aType), aCapture);
return NS_OK;
}
#endif
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsFrameLoader::SendCrossProcessKeyEvent(const nsAString& aType,
PRInt32 aKeyCode,
PRInt32 aCharCode,
PRInt32 aModifiers,
PRBool aPreventDefault)
{
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SendKeyEvent(aType, aKeyCode, aCharCode, aModifiers,
aPreventDefault);
return NS_OK;
}
#endif
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsFrameLoader::GetDelayRemoteDialogs(PRBool* aRetVal)
{
#ifdef MOZ_IPC
*aRetVal = mDelayRemoteDialogs;
#else
*aRetVal = PR_FALSE;
#endif
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::SetDelayRemoteDialogs(PRBool aDelay)
{
#ifdef MOZ_IPC
if (mChildProcess && mDelayRemoteDialogs && !aDelay) {
nsRefPtr<nsIRunnable> ev =
NS_NewRunnableMethod(mChildProcess,
&mozilla::dom::TabParent::HandleDelayedDialogs);
NS_DispatchToCurrentThread(ev);
}
mDelayRemoteDialogs = aDelay;
#endif
return NS_OK;
}
nsresult
nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
{
nsFrameLoader* dest = static_cast<nsFrameLoader*>(aDest);
dest->EnsureDocShell();
dest->MaybeCreateDocShell();
NS_ENSURE_STATE(dest->mDocShell);
nsCOMPtr<nsIDOMDocument> dummy = do_GetInterface(dest->mDocShell);
@ -1273,6 +1789,13 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
bool LoadScript(void* aCallbackData, const nsAString& aURL)
{
#ifdef MOZ_IPC
mozilla::dom::PIFrameEmbeddingParent* tabParent =
static_cast<nsFrameLoader*>(aCallbackData)->GetChildProcess();
if (tabParent) {
return tabParent->SendloadRemoteScript(nsString(aURL));
}
#endif
nsFrameLoader* fl = static_cast<nsFrameLoader*>(aCallbackData);
nsRefPtr<nsInProcessTabChildGlobal> tabChild =
static_cast<nsInProcessTabChildGlobal*>(fl->GetTabChildGlobalAsEventTarget());
@ -1309,6 +1832,14 @@ bool SendAsyncMessageToChild(void* aCallbackData,
const nsAString& aMessage,
const nsAString& aJSON)
{
#ifdef MOZ_IPC
mozilla::dom::PIFrameEmbeddingParent* tabParent =
static_cast<nsFrameLoader*>(aCallbackData)->GetChildProcess();
if (tabParent) {
return tabParent->SendsendAsyncMessageToChild(nsString(aMessage),
nsString(aJSON));
}
#endif
nsRefPtr<nsIRunnable> ev =
new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
aMessage, aJSON);
@ -1319,6 +1850,7 @@ bool SendAsyncMessageToChild(void* aCallbackData,
NS_IMETHODIMP
nsFrameLoader::GetMessageManager(nsIChromeFrameMessageManager** aManager)
{
EnsureMessageManager();
if (mMessageManager) {
CallQueryInterface(mMessageManager, aManager);
}
@ -1329,17 +1861,20 @@ nsresult
nsFrameLoader::EnsureMessageManager()
{
NS_ENSURE_STATE(mOwnerContent);
//XXX Should we create message manager also for chrome iframes?
if (!mIsTopLevelContent) {
return NS_OK;
}
EnsureDocShell();
nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return rv;
}
if (mMessageManager) {
#ifdef MOZ_IPC
if (ShouldUseRemoteProcess()) {
mMessageManager->SetCallbackData(mRemoteWidgetCreated ? this : nsnull);
}
#endif
return NS_OK;
}
nsresult rv = NS_OK;
nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(sctx);
@ -1352,17 +1887,32 @@ nsFrameLoader::EnsureMessageManager()
nsCOMPtr<nsIChromeFrameMessageManager> parentManager;
chromeWindow->GetMessageManager(getter_AddRefs(parentManager));
mMessageManager = new nsFrameMessageManager(PR_TRUE,
nsnull,
SendAsyncMessageToChild,
LoadScript,
nsnull,
static_cast<nsFrameMessageManager*>(parentManager.get()),
cx);
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
mChildMessageManager =
new nsInProcessTabChildGlobal(mDocShell, mOwnerContent, mMessageManager);
mMessageManager->SetCallbackData(this);
#ifdef MOZ_IPC
if (ShouldUseRemoteProcess()) {
mMessageManager = new nsFrameMessageManager(PR_TRUE,
nsnull,
SendAsyncMessageToChild,
LoadScript,
mRemoteWidgetCreated ? this : nsnull,
static_cast<nsFrameMessageManager*>(parentManager.get()),
cx);
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
} else
#endif
{
mMessageManager = new nsFrameMessageManager(PR_TRUE,
nsnull,
SendAsyncMessageToChild,
LoadScript,
nsnull,
static_cast<nsFrameMessageManager*>(parentManager.get()),
cx);
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
mChildMessageManager =
new nsInProcessTabChildGlobal(mDocShell, mOwnerContent, mMessageManager);
mMessageManager->SetCallbackData(this);
}
return NS_OK;
}

View File

@ -47,15 +47,34 @@
#include "nsIDocShell.h"
#include "nsStringFwd.h"
#include "nsIFrameLoader.h"
#include "nsSize.h"
#include "nsIURI.h"
#include "nsAutoPtr.h"
#include "nsFrameMessageManager.h"
class nsIContent;
class nsIURI;
class nsIFrameFrame;
class nsIView;
class nsIInProcessContentFrameMessageManager;
class AutoResetInShow;
#ifdef MOZ_IPC
namespace mozilla {
namespace dom {
class TabParent;
class PIFrameEmbeddingParent;
}
}
#ifdef MOZ_WIDGET_GTK2
typedef struct _GtkWidget GtkWidget;
#endif
#ifdef MOZ_WIDGET_QT
class QX11EmbedContainer;
#endif
#endif
class nsFrameLoader : public nsIFrameLoader
{
friend class AutoResetInShow;
@ -70,11 +89,23 @@ protected:
mInSwap(PR_FALSE),
mInShow(PR_FALSE),
mHideCalled(PR_FALSE)
#ifdef MOZ_IPC
, mDelayRemoteDialogs(PR_FALSE)
, mRemoteWidgetCreated(PR_FALSE)
, mRemoteFrame(false)
, mChildProcess(nsnull)
#if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)
, mRemoteSocket(nsnull)
#endif
#endif
{}
public:
~nsFrameLoader() {
mNeedsAsyncDestroy = PR_TRUE;
if (mMessageManager) {
mMessageManager->Disconnect();
}
nsFrameLoader::Destroy();
}
@ -113,15 +144,48 @@ public:
nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
nsRefPtr<nsFrameLoader>& aFirstToSwap,
nsRefPtr<nsFrameLoader>& aSecondToSwap);
// When IPC is enabled, destroy any associated child process.
void DestroyChild();
#ifdef MOZ_IPC
mozilla::dom::PIFrameEmbeddingParent* GetChildProcess();
#endif
nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
private:
NS_HIDDEN_(nsresult) EnsureDocShell();
#ifdef MOZ_IPC
bool ShouldUseRemoteProcess();
#endif
/**
* If we are an IPC frame, set mRemoteFrame. Otherwise, create and
* initialize mDocShell.
*/
nsresult MaybeCreateDocShell();
nsresult EnsureMessageManager();
NS_HIDDEN_(void) GetURL(nsString& aURL);
// Properly retrieves documentSize of any subdocument type.
NS_HIDDEN_(nsIntSize) GetSubDocumentSize(const nsIFrame *aIFrame);
// Updates the subdocument position and size. This gets called only
// when we have our own in-process DocShell.
NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame);
nsresult CheckURILoad(nsIURI* aURI);
void FireErrorEvent();
nsresult ReallyStartLoadingInternal();
#ifdef MOZ_IPC
// True means new process started; nothing else to do
bool TryNewProcess();
// Do the hookup necessary to actually show a remote frame once the view and
// widget are available.
bool ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view);
#endif
nsCOMPtr<nsIDocShell> mDocShell;
nsCOMPtr<nsIURI> mURIToLoad;
nsIContent *mOwnerContent; // WEAK
@ -137,6 +201,22 @@ private:
PRPackedBool mInSwap : 1;
PRPackedBool mInShow : 1;
PRPackedBool mHideCalled : 1;
#ifdef MOZ_IPC
PRPackedBool mDelayRemoteDialogs : 1;
PRPackedBool mRemoteWidgetCreated : 1;
bool mRemoteFrame;
// XXX leaking
nsCOMPtr<nsIObserver> mChildHost;
mozilla::dom::TabParent* mChildProcess;
#ifdef MOZ_WIDGET_GTK2
GtkWidget* mRemoteSocket;
#elif defined(MOZ_WIDGET_QT)
QX11EmbedContainer* mRemoteSocket;
#endif
#endif
};
#endif

View File

@ -1404,27 +1404,40 @@ nsNSElementTearoff::GetClassList(nsIDOMDOMTokenList** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsNSElementTearoff::SetCapture(PRBool aRetargetToElement)
void
nsGenericElement::SetCapture(PRBool aRetargetToElement)
{
// If there is already an active capture, ignore this request. This would
// occur if a splitter, frame resizer, etc had already captured and we don't
// want to override those.
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(nsIPresShell::GetCapturingContent());
if (node)
return NS_OK;
if (nsIPresShell::GetCapturingContent())
return;
nsIPresShell::SetCapturingContent(mContent, CAPTURE_PREVENTDRAG |
nsIPresShell::SetCapturingContent(this, CAPTURE_PREVENTDRAG |
(aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
}
NS_IMETHODIMP
nsNSElementTearoff::SetCapture(PRBool aRetargetToElement)
{
mContent->SetCapture(aRetargetToElement);
return NS_OK;
}
void
nsGenericElement::ReleaseCapture()
{
if (nsIPresShell::GetCapturingContent() == this) {
nsIPresShell::SetCapturingContent(nsnull, 0);
}
}
NS_IMETHODIMP
nsNSElementTearoff::ReleaseCapture()
{
if (nsIPresShell::GetCapturingContent() == mContent) {
nsIPresShell::SetCapturingContent(nsnull, 0);
}
mContent->ReleaseCapture();
return NS_OK;
}
@ -3303,7 +3316,7 @@ nsGenericElement::SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
if (doc) {
nsCOMPtr<nsIPresShell> shell = doc->GetShell();
if (shell) {
shell->RestyleForAnimation(this);
shell->RestyleForAnimation(this, eRestyle_Self);
}
}
}

View File

@ -746,6 +746,8 @@ public:
return NS_OK;
}
nsIDOMDOMTokenList* GetClassList(nsresult *aResult);
void SetCapture(PRBool aRetargetToElement);
void ReleaseCapture();
PRBool MozMatchesSelector(const nsAString& aSelector);
/**

View File

@ -1688,6 +1688,9 @@ GK_ATOM(TypingTxnName, "Typing")
GK_ATOM(IMETxnName, "IME")
GK_ATOM(DeleteTxnName, "Deleting")
// IPC stuff
GK_ATOM(Remote, "remote")
// Names for system metrics
GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")
GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward")

View File

@ -455,6 +455,15 @@ public:
{
return mInner->SetTrusted(aTrusted);
}
virtual void Serialize(IPC::Message* aMsg,
PRBool aSerializeInterfaceType)
{
mInner->Serialize(aMsg, aSerializeInterfaceType);
}
virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter)
{
return mInner->Deserialize(aMsg, aIter);
}
protected:
// Use nsDOMProgressEvent so that we can forward

View File

@ -45,6 +45,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
bug421622-referer.sjs \
bug514705.html \
$(NULL)
_CHROME_FILES = \
@ -53,6 +54,8 @@ _CHROME_FILES = \
test_bug429785.xul \
test_bug430050.xul \
test_bug467123.xul \
test_bug514705.xul \
bug514705_helper.xul \
test_title.xul \
title_window.xul \
test_bug549682.xul \

View File

@ -0,0 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>bug514705.html</title>
</head>
<body>
bug514705.html
</body>
</html>

View File

@ -0,0 +1,90 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Bug514705 helper"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="RunTest();">
<script type="application/javascript">
<![CDATA[
var Ci = Components.interfaces;
var imports = [ "SimpleTest", "is", "isnot", "ok" ];
for each (var import in imports) {
window[import] = window.opener.wrappedJSObject[import];
}
var locationChanged = false;
var progressChanged = false;
var refreshAttempted = false;
var listener = {
onLocationChange: function(webProgress, request, location) {
locationChanged = true;
},
onProgressChange: function(webProgress, request, curSelfProgress,
maxSelfProgress, curTotalProgress,
maxTotalProgress) {
},
onSecurityChange: function(webProgress, request, state) {
},
onStateChange: function(webProgress, request, stateFlags, status) {
if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
(stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
var test = SimpleTest;
ok (locationChanged, "onLocationChanged was called.");
ok (progressChanged, "onProgressChanged64 was called.");
ok (refreshAttempted, "onRefreshAttempted was called.");
ok (true, "onStateChange was called.");
window.close();
test.finish();
}
},
onStatusChange: function(webProgress, request, status, message) {
},
onProgressChange64 : function(webProgress, request, curSelfProgress,
maxSelfProgress, curTotalProgress,
maxTotalProgress) {
progressChanged = true;
},
onRefreshAttempted : function(webProgress, uri, millis, sameURI)
{
refreshAttempted = true;
return true;
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
iid.equals(Components.interfaces.nsIWebProgressListener2) ||
iid.equals(Components.interfaces.nsISupportsWeakReference)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
}
}
function EndTest() {
var test = SimpleTest;
window.close();
test.finish();
}
function RunTest()
{
var browser = document.getElementById('page');
var flags = Ci.nsIWebProgress.NOTIFY_ALL;
browser.webProgress.addProgressListener(listener, flags);
var script = "refreshURI = docShell.QueryInterface(Components.interfaces.nsIRefreshURI);"
+ "var ioServ = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);"
+ "var uri = ioServ.newURI('http://localhost:8888/tests/content/base/test/chrome/bug514705.html', null, null);"
+ "refreshURI.refreshURI(uri, 100, false, false);";
messageManager.loadFrameScript("data:," + script, true);
}
]]>
</script>
<browser type="content" flex="1" id="page" remote="true"/>
</window>

View File

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Bug 514705"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="RunTest();">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=421622"
target="_blank">Mozilla Bug 421622</a>
</body>
<script type="application/javascript">
<![CDATA[
//SimpleTest.waitForExplicitFinish();
todo(false, "Enable this test");
function RunTest()
{
//window.open("bug514705_helper.xul", "bug514705",
// "chrome,width=100,height=100");
}
]]>
</script>
</window>

View File

@ -0,0 +1,68 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererChild
#define mozilla_dom_DocumentRendererChild
#include "mozilla/ipc/PDocumentRendererChild.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsString.h"
#include "gfxContext.h"
class nsIDOMWindow;
namespace mozilla {
namespace ipc {
class DocumentRendererChild : public PDocumentRendererChild
{
public:
DocumentRendererChild();
virtual ~DocumentRendererChild();
bool RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
const nsString& bgcolor, const PRUint32& flags, const PRBool& flush,
PRUint32& _width, PRUint32& _height, nsCString& data);
private:
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererChild);
};
}
}
#endif

View File

@ -0,0 +1,69 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* Nokia.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererNativeIDChild
#define mozilla_dom_DocumentRendererNativeIDChild
#include "mozilla/ipc/PDocumentRendererNativeIDChild.h"
class nsIDOMWindow;
class gfxMatrix;
namespace mozilla {
namespace ipc {
class DocumentRendererNativeIDChild : public PDocumentRendererNativeIDChild
{
public:
DocumentRendererNativeIDChild();
virtual ~DocumentRendererNativeIDChild();
bool RenderDocument(nsIDOMWindow* window, const PRInt32& x,
const PRInt32& y, const PRInt32& w,
const PRInt32& h, const nsString& aBGColor,
const PRUint32& flags, const PRBool& flush,
const gfxMatrix& aMatrix,
const PRInt32& nativeID);
private:
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererNativeIDChild);
};
}
}
#endif

View File

@ -0,0 +1,67 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* Nokia.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererNativeIDParent
#define mozilla_dom_DocumentRendererNativeIDParent
#include "mozilla/ipc/PDocumentRendererNativeIDParent.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace ipc {
class DocumentRendererNativeIDParent : public PDocumentRendererNativeIDParent
{
public:
DocumentRendererNativeIDParent();
virtual ~DocumentRendererNativeIDParent();
void SetCanvas(nsICanvasRenderingContextInternal* aCanvas);
virtual bool Recv__delete__(const PRInt32& x, const PRInt32& y,
const PRInt32& w, const PRInt32& h,
const PRUint32& nativeID);
private:
nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererNativeIDParent);
};
}
}
#endif

View File

@ -0,0 +1,73 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererParent
#define mozilla_dom_DocumentRendererParent
#include "mozilla/ipc/PDocumentRendererParent.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "gfxContext.h"
namespace mozilla {
namespace ipc {
class DocumentRendererParent : public PDocumentRendererParent
{
public:
DocumentRendererParent();
virtual ~DocumentRendererParent();
void SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas,
gfxContext* ctx);
void DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
const nsCString& aData);
virtual bool Recv__delete__(const PRUint32& w, const PRUint32& h,
const nsCString& data);
private:
nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
nsRefPtr<gfxContext> mCanvasContext;
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererParent);
};
}
}
#endif

View File

@ -0,0 +1,69 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererShmemChild
#define mozilla_dom_DocumentRendererShmemChild
#include "mozilla/ipc/PDocumentRendererShmemChild.h"
class nsIDOMWindow;
class gfxMatrix;
namespace mozilla {
namespace ipc {
class DocumentRendererShmemChild : public PDocumentRendererShmemChild
{
public:
DocumentRendererShmemChild();
virtual ~DocumentRendererShmemChild();
bool RenderDocument(nsIDOMWindow *window, const PRInt32& x,
const PRInt32& y, const PRInt32& w,
const PRInt32& h, const nsString& aBGColor,
const PRUint32& flags, const PRBool& flush,
const gfxMatrix& aMatrix,
Shmem& data);
private:
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererShmemChild);
};
}
}
#endif

View File

@ -0,0 +1,67 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef mozilla_dom_DocumentRendererShmemParent
#define mozilla_dom_DocumentRendererShmemParent
#include "mozilla/ipc/PDocumentRendererShmemParent.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace ipc {
class DocumentRendererShmemParent : public PDocumentRendererShmemParent
{
public:
DocumentRendererShmemParent();
virtual ~DocumentRendererShmemParent();
void SetCanvas(nsICanvasRenderingContextInternal* aCanvas);
virtual bool Recv__delete__(const PRInt32& x, const PRInt32& y,
const PRInt32& w, const PRInt32& h,
Shmem& data);
private:
nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererShmemParent);
};
}
}
#endif

View File

@ -45,11 +45,22 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
XPIDL_MODULE = content_canvas
EXPORTS_NAMESPACES = mozilla/ipc
EXPORTS = \
nsICanvasRenderingContextInternal.h \
nsICanvasElementExternal.h \
$(NULL)
EXPORTS_mozilla/ipc = \
DocumentRendererChild.h \
DocumentRendererParent.h \
DocumentRendererShmemChild.h \
DocumentRendererShmemParent.h \
DocumentRendererNativeIDChild.h \
DocumentRendererNativeIDParent.h \
$(NULL)
XPIDLSRCS = \
nsICanvasGLPrivate.idl \
$(NULL)

View File

@ -43,9 +43,10 @@
#include "nsIDocShell.h"
#include "gfxPattern.h"
// {ed741c16-4039-469b-91da-dca742c51a9f}
// {b96168fd-6f13-4ca7-b820-e96f22e71fe5}
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0xed741c16, 0x4039, 0x469b, { 0x91, 0xda, 0xdc, 0xa7, 0x42, 0xc5, 0x1a, 0x9f } }
{ 0xb96168fd, 0x6f13, 0x4ca7, \
{ 0xb8, 0x20, 0xe9, 0x6f, 0x22, 0xe7, 0x1f, 0xe5 } }
class nsHTMLCanvasElement;
class gfxContext;
@ -56,6 +57,9 @@ namespace layers {
class CanvasLayer;
class LayerManager;
}
namespace ipc {
class Shmem;
}
}
class nsICanvasRenderingContextInternal : public nsISupports {
@ -103,6 +107,25 @@ public:
virtual already_AddRefed<CanvasLayer> GetCanvasLayer(LayerManager *mgr) = 0;
virtual void MarkContextClean() = 0;
// Redraw the dirty rectangle of this canvas.
NS_IMETHOD Redraw(const gfxRect &dirty) = 0;
// If this context can be set to use Mozilla's Shmem segments as its backing
// store, this will set it to that state. Note that if you have drawn
// anything into this canvas before changing the shmem state, it will be
// lost.
NS_IMETHOD SetIsIPC(PRBool isIPC) = 0;
// Swap this back buffer with the front, and copy its contents to the new
// back. x, y, w, and h specify the area of |back| that is dirty.
NS_IMETHOD Swap(mozilla::ipc::Shmem& back,
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) = 0;
// Sync back and front buffer, move ownership of back buffer to parent
NS_IMETHOD Swap(PRUint32 nativeID,
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,

View File

@ -0,0 +1,144 @@
/* ***** 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 Fennec Electrolysis.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#include "base/basictypes.h"
#include "gfxImageSurface.h"
#include "gfxPattern.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIDocShellTreeNode.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocument.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsCSSParser.h"
#include "nsPresContext.h"
#include "nsCOMPtr.h"
#include "nsColor.h"
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "nsLayoutUtils.h"
#include "mozilla/ipc/DocumentRendererChild.h"
using namespace mozilla::ipc;
DocumentRendererChild::DocumentRendererChild()
{}
DocumentRendererChild::~DocumentRendererChild()
{}
static void
FlushLayoutForTree(nsIDOMWindow* aWindow)
{
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
if (!piWin)
return;
// Note that because FlushPendingNotifications flushes parents, this
// is O(N^2) in docshell tree depth. However, the docshell tree is
// usually pretty shallow.
nsCOMPtr<nsIDOMDocument> domDoc;
aWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (doc) {
doc->FlushPendingNotifications(Flush_Layout);
}
nsCOMPtr<nsIDocShellTreeNode> node =
do_QueryInterface(piWin->GetDocShell());
if (node) {
PRInt32 i = 0, i_end;
node->GetChildCount(&i_end);
for (; i < i_end; ++i) {
nsCOMPtr<nsIDocShellTreeItem> item;
node->GetChildAt(i, getter_AddRefs(item));
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
if (win) {
FlushLayoutForTree(win);
}
}
}
}
bool
DocumentRendererChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
const nsString& aBGColor, const PRUint32& flags, const PRBool& flush,
PRUint32& _width, PRUint32& _height, nsCString& data)
{
if (flush)
FlushLayoutForTree(window);
nsCOMPtr<nsPresContext> presContext;
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
if (win) {
nsIDocShell* docshell = win->GetDocShell();
if (docshell) {
docshell->GetPresContext(getter_AddRefs(presContext));
}
}
if (!presContext)
return false;
nscolor bgColor;
nsCSSParser parser;
nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
nsnull, 0, &bgColor);
if (NS_FAILED(rv))
return false;
nsIPresShell* presShell = presContext->PresShell();
nsRect r(x, y, w, h);
_width = nsPresContext::AppUnitsToIntCSSPixels(w);
_height = nsPresContext::AppUnitsToIntCSSPixels(h);
// Draw directly into the output array.
data.SetLength(_width * _height * 4);
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(reinterpret_cast<PRUint8*>(const_cast<char*>(data.get())),
gfxIntSize(_width, _height),
4 * _width, gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
presShell->RenderDocument(r, flags, bgColor, ctx);
return true;
}

Some files were not shown because too many files have changed in this diff Show More