mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
[JAEGER] Merge from tracemonkey.
This commit is contained in:
commit
dd9c55abdd
@ -45,7 +45,7 @@
|
|||||||
interface nsIAccessible;
|
interface nsIAccessible;
|
||||||
interface nsIArray;
|
interface nsIArray;
|
||||||
|
|
||||||
[scriptable, uuid(035c0c0e-41e3-4985-8ad9-d9f14cdc667a)]
|
[scriptable, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
|
||||||
interface nsIAccessibleTable : nsISupports
|
interface nsIAccessibleTable : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -104,6 +104,17 @@ interface nsIAccessibleTable : nsISupports
|
|||||||
*/
|
*/
|
||||||
long getRowIndexAt(in long cellIndex);
|
long getRowIndexAt(in long cellIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the given cell index into the corresponding row and column
|
||||||
|
* indices.
|
||||||
|
*
|
||||||
|
* @param cellIndex [in] cell index to return row and column indices for
|
||||||
|
* @param rowIndex [out] row index at the given cell index
|
||||||
|
* @param columnIndex [out] column index at the given cell index
|
||||||
|
*/
|
||||||
|
void getRowAndColumnIndicesAt(in long cellIndex,
|
||||||
|
out long rowIndex, out long columnIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of columns occupied by the accessible cell at
|
* Return the number of columns occupied by the accessible cell at
|
||||||
* the specified row and column in the table. The result differs from 1 if
|
* the specified row and column in the table. The result differs from 1 if
|
||||||
|
169
accessible/src/base/AccGroupInfo.cpp
Normal file
169
accessible/src/base/AccGroupInfo.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/* ***** 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) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Alexander Surkov <surkov.alexander@gmail.com> (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 ***** */
|
||||||
|
|
||||||
|
#include "AccGroupInfo.h"
|
||||||
|
|
||||||
|
AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
|
||||||
|
mPosInSet(0), mSetSize(0), mParent(nsnull)
|
||||||
|
{
|
||||||
|
nsAccessible* parent = aItem->GetParent();
|
||||||
|
if (!parent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PRInt32 indexInParent = aItem->GetIndexInParent();
|
||||||
|
PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(aItem);
|
||||||
|
|
||||||
|
// Compute position in set.
|
||||||
|
mPosInSet = 1;
|
||||||
|
for (PRInt32 idx = indexInParent - 1; idx >=0 ; idx--) {
|
||||||
|
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||||
|
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||||
|
|
||||||
|
// If the sibling is separator then the group is ended.
|
||||||
|
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If sibling is not visible and hasn't the same base role.
|
||||||
|
if (BaseRole(siblingRole) != aRole ||
|
||||||
|
nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if it's hierarchical flatten structure, i.e. if the sibling
|
||||||
|
// level is lesser than this one then group is ended, if the sibling level
|
||||||
|
// is greater than this one then the group is split by some child elements
|
||||||
|
// (group will be continued).
|
||||||
|
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||||
|
if (siblingLevel < level) {
|
||||||
|
mParent = sibling;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip subset.
|
||||||
|
if (siblingLevel > level)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the previous item in the group has calculated group information then
|
||||||
|
// build group information for this item based on found one.
|
||||||
|
if (sibling->mGroupInfo) {
|
||||||
|
mPosInSet += sibling->mGroupInfo->mPosInSet;
|
||||||
|
mParent = sibling->mGroupInfo->mParent;
|
||||||
|
mSetSize = sibling->mGroupInfo->mSetSize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPosInSet++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute set size.
|
||||||
|
mSetSize = mPosInSet;
|
||||||
|
|
||||||
|
PRInt32 siblingCount = parent->GetChildCount();
|
||||||
|
for (PRInt32 idx = indexInParent + 1; idx < siblingCount; idx++) {
|
||||||
|
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||||
|
|
||||||
|
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||||
|
|
||||||
|
// If the sibling is separator then the group is ended.
|
||||||
|
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If sibling is visible and has the same base role
|
||||||
|
if (BaseRole(siblingRole) != aRole ||
|
||||||
|
nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// and check if it's hierarchical flatten structure.
|
||||||
|
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||||
|
if (siblingLevel < level)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Skip subset.
|
||||||
|
if (siblingLevel > level)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the next item in the group has calculated group information then
|
||||||
|
// build group information for this item based on found one.
|
||||||
|
if (sibling->mGroupInfo) {
|
||||||
|
mParent = sibling->mGroupInfo->mParent;
|
||||||
|
mSetSize = sibling->mGroupInfo->mSetSize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSetSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mParent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Compute parent.
|
||||||
|
PRUint32 parentRole = nsAccUtils::Role(parent);
|
||||||
|
|
||||||
|
// In the case of ARIA row in treegrid, return treegrid since ARIA
|
||||||
|
// groups aren't used to organize levels in ARIA treegrids.
|
||||||
|
if (aRole == nsIAccessibleRole::ROLE_ROW &&
|
||||||
|
parentRole == nsIAccessibleRole::ROLE_TREE_TABLE) {
|
||||||
|
mParent = parent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the case of ARIA tree, a tree can be arranged by using ARIA groups
|
||||||
|
// to organize levels. In this case the parent of the tree item will be
|
||||||
|
// a group and the previous treeitem of that should be the tree item
|
||||||
|
// parent. Or, if the parent is something other than a tree we will
|
||||||
|
// return that.
|
||||||
|
|
||||||
|
if (parentRole != nsIAccessibleRole::ROLE_GROUPING) {
|
||||||
|
mParent = parent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAccessible* parentPrevSibling = parent->GetSiblingAtOffset(-1);
|
||||||
|
PRUint32 parentPrevSiblingRole = nsAccUtils::Role(parentPrevSibling);
|
||||||
|
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_TEXT_LEAF) {
|
||||||
|
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
||||||
|
// although the text does not appear to be rendered, GetRenderedText()
|
||||||
|
// says that it is so we need to skip past it to find the true
|
||||||
|
// previous sibling.
|
||||||
|
parentPrevSibling = parentPrevSibling->GetSiblingAtOffset(-1);
|
||||||
|
parentPrevSiblingRole = nsAccUtils::Role(parentPrevSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Previous sibling of parent group is a tree item, this is the
|
||||||
|
// conceptual tree item parent.
|
||||||
|
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
|
||||||
|
mParent = parentPrevSibling;
|
||||||
|
}
|
96
accessible/src/base/AccGroupInfo.h
Normal file
96
accessible/src/base/AccGroupInfo.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* ***** 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) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Alexander Surkov <surkov.alexander@gmail.com> (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 ***** */
|
||||||
|
|
||||||
|
#ifndef AccGroupInfo_h_
|
||||||
|
#define AccGroupInfo_h_
|
||||||
|
|
||||||
|
#include "nsAccessible.h"
|
||||||
|
#include "nsAccUtils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate and store group information.
|
||||||
|
*/
|
||||||
|
class AccGroupInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AccGroupInfo(nsAccessible* aItem, PRUint32 aRole);
|
||||||
|
~AccGroupInfo() { }
|
||||||
|
|
||||||
|
PRInt32 PosInSet() const { return mPosInSet; }
|
||||||
|
PRUint32 SetSize() const { return mSetSize; }
|
||||||
|
nsAccessible* GetConceptualParent() const { return mParent; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create group info.
|
||||||
|
*/
|
||||||
|
static AccGroupInfo* CreateGroupInfo(nsAccessible* aAccessible)
|
||||||
|
{
|
||||||
|
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||||
|
if (role != nsIAccessibleRole::ROLE_ROW &&
|
||||||
|
role != nsIAccessibleRole::ROLE_GRID_CELL &&
|
||||||
|
role != nsIAccessibleRole::ROLE_OUTLINEITEM &&
|
||||||
|
role != nsIAccessibleRole::ROLE_OPTION &&
|
||||||
|
role != nsIAccessibleRole::ROLE_LISTITEM &&
|
||||||
|
role != nsIAccessibleRole::ROLE_MENUITEM &&
|
||||||
|
role != nsIAccessibleRole::ROLE_CHECK_MENU_ITEM &&
|
||||||
|
role != nsIAccessibleRole::ROLE_RADIO_MENU_ITEM &&
|
||||||
|
role != nsIAccessibleRole::ROLE_RADIOBUTTON &&
|
||||||
|
role != nsIAccessibleRole::ROLE_PAGETAB)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
AccGroupInfo* info = new AccGroupInfo(aAccessible, BaseRole(role));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AccGroupInfo(const AccGroupInfo&);
|
||||||
|
AccGroupInfo& operator =(const AccGroupInfo&);
|
||||||
|
|
||||||
|
static PRUint32 BaseRole(PRUint32 aRole)
|
||||||
|
{
|
||||||
|
if (aRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||||
|
aRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||||
|
return nsIAccessibleRole::ROLE_MENUITEM;
|
||||||
|
return aRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 mPosInSet;
|
||||||
|
PRUint32 mSetSize;
|
||||||
|
nsAccessible* mParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -49,6 +49,7 @@ LIBXUL_LIBRARY = 1
|
|||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
AccCollector.cpp \
|
AccCollector.cpp \
|
||||||
|
AccGroupInfo.cpp \
|
||||||
AccIterator.cpp \
|
AccIterator.cpp \
|
||||||
filters.cpp \
|
filters.cpp \
|
||||||
nsAccDocManager.cpp \
|
nsAccDocManager.cpp \
|
||||||
|
@ -221,6 +221,34 @@ nsARIAGridAccessible::GetRowIndexAt(PRInt32 aCellIndex, PRInt32 *aRowIndex)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsARIAGridAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
|
||||||
|
PRInt32* aRowIndex,
|
||||||
|
PRInt32* aColumnIndex)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRowIndex);
|
||||||
|
*aRowIndex = -1;
|
||||||
|
NS_ENSURE_ARG_POINTER(aColumnIndex);
|
||||||
|
*aColumnIndex = -1;
|
||||||
|
|
||||||
|
if (IsDefunct())
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
NS_ENSURE_ARG(aCellIndex >= 0);
|
||||||
|
|
||||||
|
PRInt32 rowCount = 0;
|
||||||
|
GetRowCount(&rowCount);
|
||||||
|
|
||||||
|
PRInt32 colsCount = 0;
|
||||||
|
GetColumnCount(&colsCount);
|
||||||
|
|
||||||
|
NS_ENSURE_ARG(aCellIndex < rowCount * colsCount);
|
||||||
|
|
||||||
|
*aColumnIndex = aCellIndex % colsCount;
|
||||||
|
*aRowIndex = aCellIndex / colsCount;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsARIAGridAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
nsARIAGridAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
||||||
PRInt32 *aExtentCount)
|
PRInt32 *aExtentCount)
|
||||||
|
@ -39,11 +39,10 @@
|
|||||||
#ifndef _nsAccCache_H_
|
#ifndef _nsAccCache_H_
|
||||||
#define _nsAccCache_H_
|
#define _nsAccCache_H_
|
||||||
|
|
||||||
|
#include "nsIAccessible.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
class nsIAccessible;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Accessible cache utils
|
// Accessible cache utils
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -367,106 +367,6 @@ nsAccUtils::GetAncestorWithRole(nsAccessible *aDescendant, PRUint32 aRole)
|
|||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
|
|
||||||
nsIContent *aStartContent,
|
|
||||||
nsIAccessible **aTreeItemParentResult)
|
|
||||||
{
|
|
||||||
*aTreeItemParentResult = nsnull;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
|
||||||
aStartTreeItem->GetParent(getter_AddRefs(parentAccessible));
|
|
||||||
if (!parentAccessible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PRUint32 startTreeItemRole = nsAccUtils::Role(aStartTreeItem);
|
|
||||||
|
|
||||||
// Calculate tree grid row parent only if the row inside of ARIA treegrid.
|
|
||||||
if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) {
|
|
||||||
PRUint32 role = nsAccUtils::Role(parentAccessible);
|
|
||||||
if (role != nsIAccessibleRole::ROLE_TREE_TABLE)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a tree or treegrid that uses aria-level to define levels, so find
|
|
||||||
// the first previous sibling accessible where level is defined to be less
|
|
||||||
// than the current level.
|
|
||||||
nsAutoString levelStr;
|
|
||||||
if (nsAccUtils::HasDefinedARIAToken(aStartContent, nsAccessibilityAtoms::aria_level) &&
|
|
||||||
aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) {
|
|
||||||
|
|
||||||
PRInt32 success;
|
|
||||||
PRInt32 level = levelStr.ToInteger(&success);
|
|
||||||
if (level > 1 && NS_SUCCEEDED(success)) {
|
|
||||||
nsCOMPtr<nsIAccessible> currentAccessible = aStartTreeItem, prevAccessible;
|
|
||||||
while (PR_TRUE) {
|
|
||||||
currentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
|
||||||
currentAccessible.swap(prevAccessible);
|
|
||||||
nsCOMPtr<nsIAccessNode> accessNode = do_QueryInterface(currentAccessible);
|
|
||||||
if (!accessNode) {
|
|
||||||
break; // Reached top of tree, no higher level found
|
|
||||||
}
|
|
||||||
PRUint32 role = nsAccUtils::Role(currentAccessible);
|
|
||||||
if (role != startTreeItemRole)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> treeItemNode;
|
|
||||||
accessNode->GetDOMNode(getter_AddRefs(treeItemNode));
|
|
||||||
nsCOMPtr<nsIContent> treeItemContent = do_QueryInterface(treeItemNode);
|
|
||||||
if (treeItemContent &&
|
|
||||||
nsAccUtils::HasDefinedARIAToken(treeItemContent,
|
|
||||||
nsAccessibilityAtoms::aria_level) &&
|
|
||||||
treeItemContent->GetAttr(kNameSpaceID_None,
|
|
||||||
nsAccessibilityAtoms::aria_level, levelStr)) {
|
|
||||||
if (levelStr.ToInteger(&success) < level && NS_SUCCEEDED(success)) {
|
|
||||||
NS_ADDREF(*aTreeItemParentResult = currentAccessible);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the case of ARIA treegrid, return its parent since ARIA group isn't
|
|
||||||
// used to organize levels in ARIA treegrids.
|
|
||||||
|
|
||||||
if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) {
|
|
||||||
NS_ADDREF(*aTreeItemParentResult = parentAccessible);
|
|
||||||
return; // The container for the tree grid rows
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the case of ARIA tree, a tree can be arranged by using role="group" to
|
|
||||||
// organize levels. In this case the parent of the tree item will be a group
|
|
||||||
// and the previous sibling of that should be the tree item parent. Or, if
|
|
||||||
// the parent is something other than a tree we will return that.
|
|
||||||
|
|
||||||
PRUint32 role = nsAccUtils::Role(parentAccessible);
|
|
||||||
if (role != nsIAccessibleRole::ROLE_GROUPING) {
|
|
||||||
NS_ADDREF(*aTreeItemParentResult = parentAccessible);
|
|
||||||
return; // The container for the tree items
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> prevAccessible;
|
|
||||||
parentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
|
||||||
if (!prevAccessible)
|
|
||||||
return;
|
|
||||||
role = nsAccUtils::Role(prevAccessible);
|
|
||||||
if (role == nsIAccessibleRole::ROLE_TEXT_LEAF) {
|
|
||||||
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
|
||||||
// although the text does not appear to be rendered, GetRenderedText() says that it is
|
|
||||||
// so we need to skip past it to find the true previous sibling
|
|
||||||
nsCOMPtr<nsIAccessible> tempAccessible = prevAccessible;
|
|
||||||
tempAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
|
||||||
if (!prevAccessible)
|
|
||||||
return;
|
|
||||||
role = nsAccUtils::Role(prevAccessible);
|
|
||||||
}
|
|
||||||
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
|
|
||||||
// Previous sibling of parent group is a tree item -- this is the conceptual tree item parent
|
|
||||||
NS_ADDREF(*aTreeItemParentResult = prevAccessible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAccessible *
|
nsAccessible *
|
||||||
nsAccUtils::GetSelectableContainer(nsAccessible *aAccessible, PRUint32 aState)
|
nsAccUtils::GetSelectableContainer(nsAccessible *aAccessible, PRUint32 aState)
|
||||||
{
|
{
|
||||||
|
@ -198,19 +198,6 @@ public:
|
|||||||
static nsAccessible * GetAncestorWithRole(nsAccessible *aDescendant,
|
static nsAccessible * GetAncestorWithRole(nsAccessible *aDescendant,
|
||||||
PRUint32 aRole);
|
PRUint32 aRole);
|
||||||
|
|
||||||
/**
|
|
||||||
* For an ARIA tree item , get the accessible that represents its conceptual parent.
|
|
||||||
* This method will use the correct method for the given way the tree is constructed.
|
|
||||||
* The conceptual parent is what the user sees as the parent, not the DOM or accessible parent.
|
|
||||||
* @param aStartTreeItem The tree item to get the parent for
|
|
||||||
* @param aStartTreeItemContent The content node for the tree item
|
|
||||||
* @param The tree item's parent, or null if none
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
|
|
||||||
nsIContent *aStartTreeItemContent,
|
|
||||||
nsIAccessible **aTreeItemParent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return single or multi selectable container for the given item.
|
* Return single or multi selectable container for the given item.
|
||||||
*
|
*
|
||||||
|
@ -131,7 +131,7 @@ void nsAccessNode::LastRelease()
|
|||||||
NS_ASSERTION(!mWeakShell, "A Shutdown() impl forgot to call its parent's Shutdown?");
|
NS_ASSERTION(!mWeakShell, "A Shutdown() impl forgot to call its parent's Shutdown?");
|
||||||
}
|
}
|
||||||
// ... then die.
|
// ... then die.
|
||||||
NS_DELETEXPCOM(this);
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include "nsIXBLAccessible.h"
|
#include "nsIXBLAccessible.h"
|
||||||
|
|
||||||
|
#include "AccGroupInfo.h"
|
||||||
#include "AccIterator.h"
|
#include "AccIterator.h"
|
||||||
#include "nsAccUtils.h"
|
#include "nsAccUtils.h"
|
||||||
#include "nsARIAMap.h"
|
#include "nsARIAMap.h"
|
||||||
@ -2125,11 +2126,12 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
|||||||
(mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM ||
|
(mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM ||
|
||||||
mRoleMapEntry->role == nsIAccessibleRole::ROLE_ROW)) {
|
mRoleMapEntry->role == nsIAccessibleRole::ROLE_ROW)) {
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> accTarget;
|
AccGroupInfo* groupInfo = GetGroupInfo();
|
||||||
nsAccUtils::GetARIATreeItemParent(this, mContent,
|
if (!groupInfo)
|
||||||
getter_AddRefs(accTarget));
|
return NS_OK_NO_RELATION_TARGET;
|
||||||
|
|
||||||
return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
|
return nsRelUtils::AddTarget(aRelationType, aRelation,
|
||||||
|
groupInfo->GetConceptualParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If accessible is in its own Window, or is the root of a document,
|
// If accessible is in its own Window, or is the root of a document,
|
||||||
@ -3091,98 +3093,24 @@ nsAccessible::GetActionRule(PRUint32 aStates)
|
|||||||
return eNoAction;
|
return eNoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AccGroupInfo*
|
||||||
|
nsAccessible::GetGroupInfo()
|
||||||
|
{
|
||||||
|
if (mGroupInfo)
|
||||||
|
return mGroupInfo;
|
||||||
|
|
||||||
|
mGroupInfo = AccGroupInfo::CreateGroupInfo(this);
|
||||||
|
return mGroupInfo;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
|
nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
|
||||||
{
|
{
|
||||||
PRUint32 role = nsAccUtils::Role(this);
|
AccGroupInfo* groupInfo = GetGroupInfo();
|
||||||
if (role != nsIAccessibleRole::ROLE_LISTITEM &&
|
if (groupInfo) {
|
||||||
role != nsIAccessibleRole::ROLE_MENUITEM &&
|
*aPosInSet = groupInfo->PosInSet();
|
||||||
role != nsIAccessibleRole::ROLE_CHECK_MENU_ITEM &&
|
*aSetSize = groupInfo->SetSize();
|
||||||
role != nsIAccessibleRole::ROLE_RADIO_MENU_ITEM &&
|
|
||||||
role != nsIAccessibleRole::ROLE_RADIOBUTTON &&
|
|
||||||
role != nsIAccessibleRole::ROLE_PAGETAB &&
|
|
||||||
role != nsIAccessibleRole::ROLE_OPTION &&
|
|
||||||
role != nsIAccessibleRole::ROLE_OUTLINEITEM &&
|
|
||||||
role != nsIAccessibleRole::ROLE_ROW &&
|
|
||||||
role != nsIAccessibleRole::ROLE_GRID_CELL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PRUint32 baseRole = role;
|
|
||||||
if (role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
|
||||||
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
|
||||||
|
|
||||||
nsAccessible* parent = GetParent();
|
|
||||||
NS_ENSURE_TRUE(parent,);
|
|
||||||
|
|
||||||
PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(this);
|
|
||||||
|
|
||||||
// Compute 'posinset'.
|
|
||||||
PRInt32 positionInGroup = 1;
|
|
||||||
for (PRInt32 idx = mIndexInParent - 1; idx >= 0; idx--) {
|
|
||||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
|
||||||
|
|
||||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
|
||||||
|
|
||||||
// If the sibling is separator then the group is ended.
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
|
||||||
break;
|
|
||||||
|
|
||||||
PRUint32 siblingBaseRole = siblingRole;
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
|
||||||
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
|
||||||
|
|
||||||
// If sibling is visible and has the same base role
|
|
||||||
if (siblingBaseRole == baseRole &&
|
|
||||||
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
|
||||||
|
|
||||||
// and check if it's hierarchical flatten structure, i.e. if the sibling
|
|
||||||
// level is lesser than this one then group is ended, if the sibling level
|
|
||||||
// is greater than this one then the group is splited by some child
|
|
||||||
// elements (group will be continued).
|
|
||||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
|
||||||
if (siblingLevel < level)
|
|
||||||
break;
|
|
||||||
else if (level == siblingLevel)
|
|
||||||
++ positionInGroup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute 'setsize'.
|
|
||||||
PRInt32 setSize = positionInGroup;
|
|
||||||
|
|
||||||
PRInt32 siblingCount = parent->GetChildCount();
|
|
||||||
for (PRInt32 idx = mIndexInParent + 1; idx < siblingCount; idx++) {
|
|
||||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
|
||||||
NS_ENSURE_TRUE(sibling,);
|
|
||||||
|
|
||||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
|
||||||
|
|
||||||
// If the sibling is separator then the group is ended.
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
|
||||||
break;
|
|
||||||
|
|
||||||
PRUint32 siblingBaseRole = siblingRole;
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
|
||||||
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
|
||||||
|
|
||||||
// If sibling is visible and has the same base role
|
|
||||||
if (siblingBaseRole == baseRole &&
|
|
||||||
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
|
||||||
|
|
||||||
// and check if it's hierarchical flatten structure.
|
|
||||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
|
||||||
if (siblingLevel < level)
|
|
||||||
break;
|
|
||||||
else if (level == siblingLevel)
|
|
||||||
++ setSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*aPosInSet = positionInGroup;
|
|
||||||
*aSetSize = setSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt32
|
PRInt32
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
|
|
||||||
|
class AccGroupInfo;
|
||||||
class nsAccessible;
|
class nsAccessible;
|
||||||
class nsAccEvent;
|
class nsAccEvent;
|
||||||
struct nsRoleMapEntry;
|
struct nsRoleMapEntry;
|
||||||
@ -324,7 +325,12 @@ protected:
|
|||||||
* Set accessible parent and index in parent.
|
* Set accessible parent and index in parent.
|
||||||
*/
|
*/
|
||||||
void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
|
void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
|
||||||
void UnbindFromParent() { mParent = nsnull; mIndexInParent = -1; }
|
void UnbindFromParent()
|
||||||
|
{
|
||||||
|
mParent = nsnull;
|
||||||
|
mIndexInParent = -1;
|
||||||
|
mGroupInfo = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return sibling accessible at the given offset.
|
* Return sibling accessible at the given offset.
|
||||||
@ -424,6 +430,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
PRUint32 GetActionRule(PRUint32 aStates);
|
PRUint32 GetActionRule(PRUint32 aStates);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return group info.
|
||||||
|
*/
|
||||||
|
AccGroupInfo* GetGroupInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires platform accessible event. It's notification method only. It does
|
* Fires platform accessible event. It's notification method only. It does
|
||||||
* change nothing on Gecko side. Don't use it until you're sure what you do
|
* change nothing on Gecko side. Don't use it until you're sure what you do
|
||||||
@ -440,6 +451,9 @@ protected:
|
|||||||
PRBool mAreChildrenInitialized;
|
PRBool mAreChildrenInitialized;
|
||||||
PRInt32 mIndexInParent;
|
PRInt32 mIndexInParent;
|
||||||
|
|
||||||
|
nsAutoPtr<AccGroupInfo> mGroupInfo;
|
||||||
|
friend class AccGroupInfo;
|
||||||
|
|
||||||
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
|
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -953,6 +953,26 @@ nsHTMLTableAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow)
|
|||||||
return (*aRow == -1 || column == -1) ? NS_ERROR_INVALID_ARG : NS_OK;
|
return (*aRow == -1 || column == -1) ? NS_ERROR_INVALID_ARG : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLTableAccessible::GetRowAndColumnIndicesAt(PRInt32 aIndex,
|
||||||
|
PRInt32* aRowIdx,
|
||||||
|
PRInt32* aColumnIdx)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRowIdx);
|
||||||
|
*aRowIdx = -1;
|
||||||
|
NS_ENSURE_ARG_POINTER(aColumnIdx);
|
||||||
|
*aColumnIdx = -1;
|
||||||
|
|
||||||
|
if (IsDefunct())
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsITableLayout* tableLayout = GetTableLayout();
|
||||||
|
if (tableLayout)
|
||||||
|
tableLayout->GetRowAndColumnByIndex(aIndex, aRowIdx, aColumnIdx);
|
||||||
|
|
||||||
|
return (*aRowIdx == -1 || *aColumnIdx == -1) ? NS_ERROR_INVALID_ARG : NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
|
nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
|
||||||
PRInt32 aColumnIndex,
|
PRInt32 aColumnIndex,
|
||||||
|
@ -666,33 +666,28 @@ __try {
|
|||||||
if (!tableAcc)
|
if (!tableAcc)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
PRInt32 row = -1;
|
PRInt32 rowIdx = -1, columnIdx = -1;
|
||||||
nsresult rv = tableAcc->GetRowIndexAt(aIndex, &row);
|
nsresult rv = tableAcc->GetRowAndColumnIndicesAt(aIndex, &rowIdx, &columnIdx);
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return GetHRESULT(rv);
|
|
||||||
|
|
||||||
PRInt32 column = -1;
|
|
||||||
rv = tableAcc->GetColumnIndexAt(aIndex, &column);
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return GetHRESULT(rv);
|
return GetHRESULT(rv);
|
||||||
|
|
||||||
PRInt32 rowExtents = 0;
|
PRInt32 rowExtents = 0;
|
||||||
rv = tableAcc->GetRowExtentAt(row, column, &rowExtents);
|
rv = tableAcc->GetRowExtentAt(rowIdx, columnIdx, &rowExtents);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return GetHRESULT(rv);
|
return GetHRESULT(rv);
|
||||||
|
|
||||||
PRInt32 columnExtents = 0;
|
PRInt32 columnExtents = 0;
|
||||||
rv = tableAcc->GetColumnExtentAt(row, column, &columnExtents);
|
rv = tableAcc->GetColumnExtentAt(rowIdx, columnIdx, &columnExtents);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return GetHRESULT(rv);
|
return GetHRESULT(rv);
|
||||||
|
|
||||||
PRBool isSelected = PR_FALSE;
|
PRBool isSelected = PR_FALSE;
|
||||||
rv = tableAcc->IsCellSelected(row, column, &isSelected);
|
rv = tableAcc->IsCellSelected(rowIdx, columnIdx, &isSelected);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return GetHRESULT(rv);
|
return GetHRESULT(rv);
|
||||||
|
|
||||||
*aRow = row;
|
*aRow = rowIdx;
|
||||||
*aColumn = column;
|
*aColumn = columnIdx;
|
||||||
*aRowExtents = rowExtents;
|
*aRowExtents = rowExtents;
|
||||||
*aColumnExtents = columnExtents;
|
*aColumnExtents = columnExtents;
|
||||||
*aIsSelected = isSelected;
|
*aIsSelected = isSelected;
|
||||||
|
@ -412,6 +412,28 @@ nsXULListboxAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXULListboxAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
|
||||||
|
PRInt32* aRowIndex,
|
||||||
|
PRInt32* aColumnIndex)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRowIndex);
|
||||||
|
*aRowIndex = -1;
|
||||||
|
NS_ENSURE_ARG_POINTER(aColumnIndex);
|
||||||
|
*aColumnIndex = -1;
|
||||||
|
|
||||||
|
if (IsDefunct())
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRInt32 columnCount = 0;
|
||||||
|
nsresult rv = GetColumnCount(&columnCount);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
*aColumnIndex = aCellIndex % columnCount;
|
||||||
|
*aRowIndex = aCellIndex / columnCount;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXULListboxAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
nsXULListboxAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
||||||
PRInt32 *aCellSpans)
|
PRInt32 *aCellSpans)
|
||||||
|
@ -411,6 +411,28 @@ nsXULTreeGridAccessible::GetRowIndexAt(PRInt32 aCellIndex, PRInt32 *aRowIndex)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXULTreeGridAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
|
||||||
|
PRInt32* aRowIndex,
|
||||||
|
PRInt32* aColumnIndex)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRowIndex);
|
||||||
|
*aRowIndex = -1;
|
||||||
|
NS_ENSURE_ARG_POINTER(aColumnIndex);
|
||||||
|
*aColumnIndex = -1;
|
||||||
|
|
||||||
|
if (IsDefunct())
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRInt32 columnCount = 0;
|
||||||
|
nsresult rv = GetColumnCount(&columnCount);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
*aColumnIndex = aCellIndex % columnCount;
|
||||||
|
*aRowIndex = aCellIndex / columnCount;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXULTreeGridAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
|
nsXULTreeGridAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
|
||||||
PRInt32 aColumnIndex,
|
PRInt32 aColumnIndex,
|
||||||
|
@ -224,7 +224,7 @@ function testTableIndexes(aIdentifier, aIdxes)
|
|||||||
|
|
||||||
if (idx != - 1) {
|
if (idx != - 1) {
|
||||||
|
|
||||||
// getRowAtIndex
|
// getRowIndexAt
|
||||||
var origRowIdx = rowIdx;
|
var origRowIdx = rowIdx;
|
||||||
while (origRowIdx > 0 &&
|
while (origRowIdx > 0 &&
|
||||||
aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
|
aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
|
||||||
@ -237,9 +237,9 @@ function testTableIndexes(aIdentifier, aIdxes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
is(obtainedRowIdx, origRowIdx,
|
is(obtainedRowIdx, origRowIdx,
|
||||||
id + ": row for index " + idx +" is not correct");
|
id + ": row for index " + idx + " is not correct (getRowIndexAt)");
|
||||||
|
|
||||||
// getColumnAtIndex
|
// getColumnIndexAt
|
||||||
var origColIdx = colIdx;
|
var origColIdx = colIdx;
|
||||||
while (origColIdx > 0 &&
|
while (origColIdx > 0 &&
|
||||||
aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1])
|
aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1])
|
||||||
@ -252,7 +252,21 @@ function testTableIndexes(aIdentifier, aIdxes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
is(obtainedColIdx, origColIdx,
|
is(obtainedColIdx, origColIdx,
|
||||||
id + ": column for index " + idx +" is not correct");
|
id + ": column for index " + idx + " is not correct (getColumnIndexAt)");
|
||||||
|
|
||||||
|
// getRowAndColumnIndicesAt
|
||||||
|
var obtainedRowIdxObj = { }, obtainedColIdxObj = { };
|
||||||
|
try {
|
||||||
|
tableAcc.getRowAndColumnIndicesAt(idx, obtainedRowIdxObj,
|
||||||
|
obtainedColIdxObj);
|
||||||
|
} catch (e) {
|
||||||
|
ok(false, id + ": can't get row and column indices for cell index " + idx + "," + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
is(obtainedRowIdxObj.value, origRowIdx,
|
||||||
|
id + ": row for index " + idx + " is not correct (getRowAndColumnIndicesAt)");
|
||||||
|
is(obtainedColIdxObj.value, origColIdx,
|
||||||
|
id + ": column for index " + idx + " is not correct (getRowAndColumnIndicesAt)");
|
||||||
|
|
||||||
if (cellAcc) {
|
if (cellAcc) {
|
||||||
|
|
||||||
|
@ -134,5 +134,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>CGDisableCoalescedUpdates</key>
|
<key>CGDisableCoalescedUpdates</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.5</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -320,8 +320,6 @@ pref("browser.tabs.loadInBackground", true);
|
|||||||
pref("browser.tabs.opentabfor.middleclick", true);
|
pref("browser.tabs.opentabfor.middleclick", true);
|
||||||
pref("browser.tabs.loadDivertedInBackground", false);
|
pref("browser.tabs.loadDivertedInBackground", false);
|
||||||
pref("browser.tabs.loadBookmarksInBackground", false);
|
pref("browser.tabs.loadBookmarksInBackground", false);
|
||||||
pref("browser.tabs.tabMinWidth", 100);
|
|
||||||
pref("browser.tabs.tabMaxWidth", 250);
|
|
||||||
pref("browser.tabs.tabClipWidth", 140);
|
pref("browser.tabs.tabClipWidth", 140);
|
||||||
|
|
||||||
// Where to show tab close buttons:
|
// Where to show tab close buttons:
|
||||||
|
@ -130,7 +130,7 @@ var FullZoom = {
|
|||||||
|
|
||||||
this._siteSpecificPref =
|
this._siteSpecificPref =
|
||||||
gPrefService.getBoolPref("browser.zoom.siteSpecific");
|
gPrefService.getBoolPref("browser.zoom.siteSpecific");
|
||||||
this.updateBackgroundTabs =
|
this.updateBackgroundTabs =
|
||||||
gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
|
gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
|
||||||
// Listen for changes to the browser.zoom branch so we can enable/disable
|
// Listen for changes to the browser.zoom branch so we can enable/disable
|
||||||
// updating background tabs and per-site saving and restoring of zoom levels.
|
// updating background tabs and per-site saving and restoring of zoom levels.
|
||||||
|
@ -22,12 +22,18 @@ tabbrowser {
|
|||||||
|
|
||||||
.tabbrowser-tab {
|
.tabbrowser-tab {
|
||||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
|
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabbrowser-tab:not([pinned]) {
|
||||||
-moz-box-flex: 100;
|
-moz-box-flex: 100;
|
||||||
|
max-width: 250px;
|
||||||
|
min-width: 100px;
|
||||||
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbrowser-tab:not([fadein]) {
|
.tabbrowser-tab:not([fadein]) {
|
||||||
max-width: 1px !important;
|
max-width: 1px;
|
||||||
min-width: 1px !important;
|
min-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbrowser-tab[fadein]:not([pinned]) {
|
.tabbrowser-tab[fadein]:not([pinned]) {
|
||||||
@ -48,9 +54,6 @@ tabbrowser {
|
|||||||
|
|
||||||
.tabbrowser-tab[pinned] {
|
.tabbrowser-tab[pinned] {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
-moz-box-flex: 0;
|
|
||||||
min-width: 0 !important;
|
|
||||||
max-width: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbrowser-tab[pinned] > .tab-text {
|
.tabbrowser-tab[pinned] > .tab-text {
|
||||||
@ -81,6 +84,12 @@ toolbar[printpreview="true"] {
|
|||||||
-moz-box-ordinal-group: 10;
|
-moz-box-ordinal-group: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
|
#main-window[inFullscreen] > #appmenu-button-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
%endif
|
||||||
|
|
||||||
toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
|
toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -4014,7 +4014,7 @@ var XULBrowserWindow = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onLinkIconAvailable: function (aBrowser, aIconURL) {
|
onLinkIconAvailable: function (aIconURL) {
|
||||||
if (gProxyFavIcon && gBrowser.userTypedValue === null)
|
if (gProxyFavIcon && gBrowser.userTypedValue === null)
|
||||||
PageProxySetIcon(aIconURL); // update the favicon in the URL bar
|
PageProxySetIcon(aIconURL); // update the favicon in the URL bar
|
||||||
},
|
},
|
||||||
@ -4490,21 +4490,16 @@ var CombinedStopReload = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var TabsProgressListener = {
|
var TabsProgressListener = {
|
||||||
onProgressChange: function (aBrowser, aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress) {
|
|
||||||
},
|
|
||||||
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
|
||||||
#ifdef MOZ_CRASHREPORTER
|
#ifdef MOZ_CRASHREPORTER
|
||||||
|
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
if (aRequest instanceof Ci.nsIChannel &&
|
if (aRequest instanceof Ci.nsIChannel &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
|
||||||
gCrashReporter.enabled) {
|
gCrashReporter.enabled) {
|
||||||
gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
|
gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
|
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
|
||||||
// Filter out any sub-frame loads
|
// Filter out any sub-frame loads
|
||||||
@ -4512,9 +4507,6 @@ var TabsProgressListener = {
|
|||||||
FullZoom.onLocationChange(aLocationURI, false, aBrowser);
|
FullZoom.onLocationChange(aLocationURI, false, aBrowser);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStatusChange: function (aBrowser, aWebProgress, aRequest, aStatus, aMessage) {
|
|
||||||
},
|
|
||||||
|
|
||||||
onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
|
onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
|
||||||
if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
|
if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
|
||||||
let brandBundle = document.getElementById("bundle_brand");
|
let brandBundle = document.getElementById("bundle_brand");
|
||||||
@ -4561,9 +4553,6 @@ var TabsProgressListener = {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
|
||||||
|
|
||||||
onSecurityChange: function (aBrowser, aWebProgress, aRequest, aState) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4727,12 +4716,12 @@ var TabsOnTop = {
|
|||||||
|
|
||||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
function updateAppButtonDisplay() {
|
function updateAppButtonDisplay() {
|
||||||
var menubarHidden =
|
var displayAppButton = window.menubar.visible &&
|
||||||
document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
|
document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
|
||||||
|
|
||||||
document.getElementById("appmenu-button-container").hidden = !menubarHidden;
|
document.getElementById("appmenu-button-container").hidden = !displayAppButton;
|
||||||
|
|
||||||
if (menubarHidden)
|
if (displayAppButton)
|
||||||
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
|
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
|
||||||
else
|
else
|
||||||
document.documentElement.removeAttribute("chromemargin");
|
document.documentElement.removeAttribute("chromemargin");
|
||||||
@ -7772,6 +7761,10 @@ var TabContextMenu = {
|
|||||||
Cc["@mozilla.org/browser/sessionstore;1"].
|
Cc["@mozilla.org/browser/sessionstore;1"].
|
||||||
getService(Ci.nsISessionStore).
|
getService(Ci.nsISessionStore).
|
||||||
getClosedTabCount(window) == 0;
|
getClosedTabCount(window) == 0;
|
||||||
|
|
||||||
|
// Only one of pin/unpin should be visible
|
||||||
|
document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
|
||||||
|
document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,6 +126,12 @@
|
|||||||
accesskey="&openTabInNewWindow.accesskey;"
|
accesskey="&openTabInNewWindow.accesskey;"
|
||||||
tbattr="tabbrowser-multiple"
|
tbattr="tabbrowser-multiple"
|
||||||
oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
|
oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
|
||||||
|
<menuitem id="context_pinTab" label="&pinTab.label;"
|
||||||
|
accesskey="&pinTab.accesskey;"
|
||||||
|
oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/>
|
||||||
|
<menuitem id="context_unpinTab" label="&unpinTab.label;" hidden="true"
|
||||||
|
accesskey="&unpinTab.accesskey;"
|
||||||
|
oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/>
|
||||||
<menuseparator/>
|
<menuseparator/>
|
||||||
<menuitem id="context_bookmarkTab"
|
<menuitem id="context_bookmarkTab"
|
||||||
label="&bookmarkThisTab.label;"
|
label="&bookmarkThisTab.label;"
|
||||||
|
@ -122,6 +122,12 @@ Sanitizer.prototype = {
|
|||||||
// facility for timespan-based eviction. Wipe it.
|
// facility for timespan-based eviction. Wipe it.
|
||||||
cacheService.evictEntries(Ci.nsICache.STORE_ANYWHERE);
|
cacheService.evictEntries(Ci.nsICache.STORE_ANYWHERE);
|
||||||
} catch(er) {}
|
} catch(er) {}
|
||||||
|
|
||||||
|
var imageCache = Cc["@mozilla.org/image/cache;1"].
|
||||||
|
getService(Ci.imgICache);
|
||||||
|
try {
|
||||||
|
imageCache.clearCache(false); // true=chrome, false=content
|
||||||
|
} catch(er) {}
|
||||||
},
|
},
|
||||||
|
|
||||||
get canClear()
|
get canClear()
|
||||||
|
@ -263,6 +263,53 @@
|
|||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method name="_callProgressListeners">
|
||||||
|
<parameter name="aBrowser"/>
|
||||||
|
<parameter name="aMethod"/>
|
||||||
|
<parameter name="aArguments"/>
|
||||||
|
<parameter name="aCallGlobalListeners"/>
|
||||||
|
<parameter name="aCallTabsListeners"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var rv = true;
|
||||||
|
|
||||||
|
if (!aBrowser)
|
||||||
|
aBrowser = this.mCurrentBrowser;
|
||||||
|
|
||||||
|
if (aCallGlobalListeners != false &&
|
||||||
|
aBrowser == this.mCurrentBrowser) {
|
||||||
|
this.mProgressListeners.forEach(function (p) {
|
||||||
|
if (aMethod in p) {
|
||||||
|
try {
|
||||||
|
if (!p[aMethod].apply(p, aArguments))
|
||||||
|
rv = false;
|
||||||
|
} catch (e) {
|
||||||
|
// don't inhibit other listeners
|
||||||
|
Components.utils.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCallTabsListeners != false) {
|
||||||
|
aArguments.unshift(aBrowser);
|
||||||
|
|
||||||
|
this.mTabsProgressListeners.forEach(function (p) {
|
||||||
|
if (aMethod in p) {
|
||||||
|
try {
|
||||||
|
if (!p[aMethod].apply(p, aArguments))
|
||||||
|
rv = false;
|
||||||
|
} catch (e) {
|
||||||
|
// don't inhibit other listeners
|
||||||
|
Components.utils.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
<!-- A web progress listener object definition for a given tab. -->
|
<!-- A web progress listener object definition for a given tab. -->
|
||||||
<method name="mTabProgressListener">
|
<method name="mTabProgressListener">
|
||||||
<parameter name="aTab"/>
|
<parameter name="aTab"/>
|
||||||
@ -293,10 +340,14 @@
|
|||||||
delete this.mTabBrowser;
|
delete this.mTabBrowser;
|
||||||
},
|
},
|
||||||
|
|
||||||
onProgressChange : function (aWebProgress, aRequest,
|
_callProgressListeners: function () {
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
Array.unshift(arguments, this.mBrowser);
|
||||||
aCurTotalProgress, aMaxTotalProgress)
|
return this.mTabBrowser._callProgressListeners.apply(this.mTabBrowser, arguments);
|
||||||
{
|
},
|
||||||
|
|
||||||
|
onProgressChange: function (aWebProgress, aRequest,
|
||||||
|
aCurSelfProgress, aMaxSelfProgress,
|
||||||
|
aCurTotalProgress, aMaxTotalProgress) {
|
||||||
this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
|
this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
|
||||||
|
|
||||||
if (this.mBlank)
|
if (this.mBlank)
|
||||||
@ -312,46 +363,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
this._callProgressListeners("onProgressChange",
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
[aWebProgress, aRequest,
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
aCurSelfProgress, aMaxSelfProgress,
|
||||||
if (p)
|
aCurTotalProgress, aMaxTotalProgress]);
|
||||||
try {
|
|
||||||
p.onProgressChange(aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onProgressChange(this.mBrowser, aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onProgressChange64 : function (aWebProgress, aRequest,
|
onProgressChange64: function (aWebProgress, aRequest,
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
aCurSelfProgress, aMaxSelfProgress,
|
||||||
aCurTotalProgress, aMaxTotalProgress)
|
aCurTotalProgress, aMaxTotalProgress) {
|
||||||
{
|
|
||||||
return this.onProgressChange(aWebProgress, aRequest,
|
return this.onProgressChange(aWebProgress, aRequest,
|
||||||
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
|
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
|
||||||
aMaxTotalProgress);
|
aMaxTotalProgress);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
|
onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
{
|
|
||||||
if (!aRequest)
|
if (!aRequest)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -436,33 +462,19 @@
|
|||||||
this.mTabBrowser.mIsBusy = false;
|
this.mTabBrowser.mIsBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
if (oldBlank) {
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
this._callProgressListeners("onUpdateCurrentBrowser",
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
[aStateFlags, aStatus, "", 0],
|
||||||
if (p)
|
true, false);
|
||||||
try {
|
} else {
|
||||||
if (!oldBlank)
|
this._callProgressListeners("onStateChange",
|
||||||
p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
[aWebProgress, aRequest, aStateFlags, aStatus],
|
||||||
// make sure that the visible status of new blank tabs is correctly set
|
true, false);
|
||||||
else if ("onUpdateCurrentBrowser" in p)
|
|
||||||
p.onUpdateCurrentBrowser(aStateFlags, aStatus, "", 0);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
this._callProgressListeners("onStateChange",
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
[aWebProgress, aRequest, aStateFlags, aStatus],
|
||||||
if (p)
|
false);
|
||||||
try {
|
|
||||||
p.onStateChange(this.mBrowser, aWebProgress, aRequest, aStateFlags, aStatus);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aStateFlags & (nsIWebProgressListener.STATE_START |
|
if (aStateFlags & (nsIWebProgressListener.STATE_START |
|
||||||
nsIWebProgressListener.STATE_STOP)) {
|
nsIWebProgressListener.STATE_STOP)) {
|
||||||
@ -474,8 +486,7 @@
|
|||||||
this.mStatus = aStatus;
|
this.mStatus = aStatus;
|
||||||
},
|
},
|
||||||
|
|
||||||
onLocationChange : function(aWebProgress, aRequest, aLocation)
|
onLocationChange: function (aWebProgress, aRequest, aLocation) {
|
||||||
{
|
|
||||||
// The document loaded correctly, clear the value if we should
|
// The document loaded correctly, clear the value if we should
|
||||||
if (this.mBrowser.userTypedClear > 0)
|
if (this.mBrowser.userTypedClear > 0)
|
||||||
this.mBrowser.userTypedValue = null;
|
this.mBrowser.userTypedValue = null;
|
||||||
@ -497,129 +508,35 @@
|
|||||||
browserHistory.registerOpenPage(aLocation);
|
browserHistory.registerOpenPage(aLocation);
|
||||||
|
|
||||||
if (!this.mBlank) {
|
if (!this.mBlank) {
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
this._callProgressListeners("onLocationChange",
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
[aWebProgress, aRequest, aLocation]);
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onLocationChange(aWebProgress, aRequest, aLocation);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mBrowser.lastURI = aLocation;
|
this.mBrowser.lastURI = aLocation;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
|
onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
|
||||||
{
|
|
||||||
if (this.mBlank)
|
if (this.mBlank)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
this._callProgressListeners("onStatusChange",
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
[aWebProgress, aRequest, aStatus, aMessage]);
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onStatusChange(this.mBrowser, aWebProgress, aRequest, aStatus, aMessage);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mMessage = aMessage;
|
this.mMessage = aMessage;
|
||||||
},
|
},
|
||||||
|
|
||||||
onSecurityChange : function(aWebProgress, aRequest, aState)
|
onSecurityChange: function (aWebProgress, aRequest, aState) {
|
||||||
{
|
this._callProgressListeners("onSecurityChange",
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
[aWebProgress, aRequest, aState]);
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onSecurityChange(aWebProgress, aRequest, aState);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onSecurityChange(this.mBrowser, aWebProgress, aRequest, aState);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onRefreshAttempted : function(aWebProgress, aURI, aDelay, aSameURI)
|
onRefreshAttempted: function (aWebProgress, aURI, aDelay, aSameURI) {
|
||||||
{
|
return this._callProgressListeners("onRefreshAttempted",
|
||||||
var allowRefresh = true;
|
[aWebProgress, aURI, aDelay, aSameURI]);
|
||||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mProgressListeners[i];
|
|
||||||
if (p && "onRefreshAttempted" in p) {
|
|
||||||
try {
|
|
||||||
if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI))
|
|
||||||
allowRefresh = false;
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
|
||||||
if (p && "onRefreshAttempted" in p) {
|
|
||||||
try {
|
|
||||||
if (!p.onRefreshAttempted(this.mBrowser, aWebProgress, aURI, aDelay, aSameURI))
|
|
||||||
allowRefresh = false;
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allowRefresh;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
QueryInterface : function(aIID)
|
QueryInterface: function (aIID) {
|
||||||
{
|
|
||||||
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
|
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
|
||||||
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
|
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
|
||||||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
|
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
|
||||||
@ -663,29 +580,7 @@
|
|||||||
|
|
||||||
this.updateIcon(aTab);
|
this.updateIcon(aTab);
|
||||||
|
|
||||||
if (browser == this.mCurrentBrowser) {
|
this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
|
||||||
for (let i = 0; i < this.mProgressListeners.length; i++) {
|
|
||||||
let p = this.mProgressListeners[i];
|
|
||||||
if ('onLinkIconAvailable' in p)
|
|
||||||
try {
|
|
||||||
p.onLinkIconAvailable(browser, browser.mIconURL);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.mTabsProgressListeners.length; i++) {
|
|
||||||
let p = this.mTabsProgressListeners[i];
|
|
||||||
if ('onLinkIconAvailable' in p)
|
|
||||||
try {
|
|
||||||
p.onLinkIconAvailable(browser, browser.mIconURL);
|
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]>
|
]]>
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
@ -864,26 +759,20 @@
|
|||||||
var webProgress = this.mCurrentBrowser.webProgress;
|
var webProgress = this.mCurrentBrowser.webProgress;
|
||||||
var securityUI = this.mCurrentBrowser.securityUI;
|
var securityUI = this.mCurrentBrowser.securityUI;
|
||||||
|
|
||||||
var i, p;
|
this._callProgressListeners(null, "onLocationChange",
|
||||||
for (i = 0; i < this.mProgressListeners.length; i++) {
|
[webProgress, null, loc], true, false);
|
||||||
p = this.mProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
try {
|
|
||||||
p.onLocationChange(webProgress, null, loc);
|
|
||||||
if (securityUI)
|
|
||||||
p.onSecurityChange(webProgress, null, securityUI.state);
|
|
||||||
|
|
||||||
// make sure that all status indicators are properly updated
|
if (securityUI) {
|
||||||
if ("onUpdateCurrentBrowser" in p) {
|
this._callProgressListeners(null, "onSecurityChange",
|
||||||
let listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;
|
[webProgress, null, securityUI.state], true, false);
|
||||||
if (listener && listener.mStateFlags)
|
}
|
||||||
p.onUpdateCurrentBrowser(listener.mStateFlags, listener.mStatus,
|
|
||||||
listener.mMessage, listener.mTotalProgress);
|
var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;
|
||||||
}
|
if (listener && listener.mStateFlags) {
|
||||||
} catch (e) {
|
this._callProgressListeners(null, "onUpdateCurrentBrowser",
|
||||||
// don't inhibit other listeners or following code
|
[listener.mStateFlags, listener.mStatus,
|
||||||
Components.utils.reportError(e);
|
listener.mMessage, listener.mTotalProgress],
|
||||||
}
|
true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't switch the fast find or update the titlebar (bug 540248) - this tab switch is temporary
|
// Don't switch the fast find or update the titlebar (bug 540248) - this tab switch is temporary
|
||||||
@ -898,32 +787,22 @@
|
|||||||
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
|
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
|
||||||
if (this.mCurrentTab.hasAttribute("busy") && !this.mIsBusy) {
|
if (this.mCurrentTab.hasAttribute("busy") && !this.mIsBusy) {
|
||||||
this.mIsBusy = true;
|
this.mIsBusy = true;
|
||||||
for (i = 0; i < this.mProgressListeners.length; i++) {
|
this._callProgressListeners(null, "onStateChange",
|
||||||
p = this.mProgressListeners[i];
|
[webProgress, null,
|
||||||
if (p)
|
nsIWebProgressListener.STATE_START |
|
||||||
try {
|
nsIWebProgressListener.STATE_IS_NETWORK, 0],
|
||||||
p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_IS_NETWORK, 0);
|
true, false);
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners or following code
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the new tab is not busy, and our current state is busy, then
|
// If the new tab is not busy, and our current state is busy, then
|
||||||
// we need to fire a stop to all progress listeners.
|
// we need to fire a stop to all progress listeners.
|
||||||
if (!this.mCurrentTab.hasAttribute("busy") && this.mIsBusy) {
|
if (!this.mCurrentTab.hasAttribute("busy") && this.mIsBusy) {
|
||||||
this.mIsBusy = false;
|
this.mIsBusy = false;
|
||||||
for (i = 0; i < this.mProgressListeners.length; i++) {
|
this._callProgressListeners(null, "onStateChange",
|
||||||
p = this.mProgressListeners[i];
|
[webProgress, null,
|
||||||
if (p)
|
nsIWebProgressListener.STATE_STOP |
|
||||||
try {
|
nsIWebProgressListener.STATE_IS_NETWORK, 0],
|
||||||
p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_STOP | nsIWebProgressListener.STATE_IS_NETWORK, 0);
|
true, false);
|
||||||
} catch (e) {
|
|
||||||
// don't inhibit other listeners or following code
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TabSelect events are suppressed during preview mode to avoid confusing extensions and other bits of code
|
// TabSelect events are suppressed during preview mode to avoid confusing extensions and other bits of code
|
||||||
@ -1054,11 +933,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove all our progress listeners from the active browser's filter.
|
// Remove all our progress listeners from the active browser's filter.
|
||||||
for (var i = 0; i < this.mProgressListeners.length; i++) {
|
this.mProgressListeners.forEach(filter.removeProgressListener, filter);
|
||||||
var p = this.mProgressListeners[i];
|
|
||||||
if (p)
|
|
||||||
filter.removeProgressListener(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wire up a progress listener to our filter.
|
// Wire up a progress listener to our filter.
|
||||||
const listener = this.mTabProgressListener(this.mCurrentTab,
|
const listener = this.mTabProgressListener(this.mCurrentTab,
|
||||||
@ -1210,9 +1085,6 @@
|
|||||||
t.setAttribute("label", aURI);
|
t.setAttribute("label", aURI);
|
||||||
|
|
||||||
t.setAttribute("crop", "end");
|
t.setAttribute("crop", "end");
|
||||||
t.style.maxWidth = this.tabContainer.mTabMaxWidth + "px";
|
|
||||||
t.style.minWidth = this.tabContainer.mTabMinWidth + "px";
|
|
||||||
t.width = 0;
|
|
||||||
t.setAttribute("validate", "never");
|
t.setAttribute("validate", "never");
|
||||||
t.setAttribute("onerror", "this.removeAttribute('image');");
|
t.setAttribute("onerror", "this.removeAttribute('image');");
|
||||||
t.className = "tabbrowser-tab";
|
t.className = "tabbrowser-tab";
|
||||||
@ -1766,12 +1638,8 @@
|
|||||||
<parameter name="aListener"/>
|
<parameter name="aListener"/>
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
for (var i = 0; i < this.mProgressListeners.length; i++) {
|
this.mProgressListeners =
|
||||||
if (this.mProgressListeners[i] == aListener) {
|
this.mProgressListeners.filter(function (l) l != aListener);
|
||||||
this.mProgressListeners.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.mTabbedMode)
|
if (!this.mTabbedMode)
|
||||||
// Don't forget to remove it from the filter we hooked it up to
|
// Don't forget to remove it from the filter we hooked it up to
|
||||||
@ -1792,9 +1660,8 @@
|
|||||||
<parameter name="aListener"/>
|
<parameter name="aListener"/>
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
var pos = this.mTabsProgressListeners.indexOf(aListener);
|
this.mTabsProgressListeners =
|
||||||
if (pos >= 0)
|
this.mTabsProgressListeners.filter(function (l) l != aListener);
|
||||||
this.mTabsProgressListeners.splice(pos, 1);
|
|
||||||
]]>
|
]]>
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
@ -2505,8 +2372,6 @@
|
|||||||
<implementation implements="nsIDOMEventListener">
|
<implementation implements="nsIDOMEventListener">
|
||||||
<constructor>
|
<constructor>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
this.mTabMinWidth = Services.prefs.getIntPref("browser.tabs.tabMinWidth");
|
|
||||||
this.mTabMaxWidth = Services.prefs.getIntPref("browser.tabs.tabMaxWidth");
|
|
||||||
this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
|
this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
|
||||||
this.mCloseButtons = Services.prefs.getIntPref("browser.tabs.closeButtons");
|
this.mCloseButtons = Services.prefs.getIntPref("browser.tabs.closeButtons");
|
||||||
this._closeWindowWithLastTab = Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
|
this._closeWindowWithLastTab = Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
|
||||||
@ -2514,9 +2379,6 @@
|
|||||||
var tab = this.firstChild;
|
var tab = this.firstChild;
|
||||||
tab.setAttribute("label",
|
tab.setAttribute("label",
|
||||||
this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle"));
|
this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle"));
|
||||||
tab.style.minWidth = this.mTabMinWidth + "px";
|
|
||||||
tab.style.maxWidth = this.mTabMaxWidth + "px";
|
|
||||||
tab.width = 0;
|
|
||||||
tab.setAttribute("crop", "end");
|
tab.setAttribute("crop", "end");
|
||||||
tab.setAttribute("validate", "never");
|
tab.setAttribute("validate", "never");
|
||||||
tab.setAttribute("onerror", "this.removeAttribute('image');");
|
tab.setAttribute("onerror", "this.removeAttribute('image');");
|
||||||
|
@ -125,6 +125,7 @@ _BROWSER_FILES = \
|
|||||||
browser_bug491431.js \
|
browser_bug491431.js \
|
||||||
browser_bug495058.js \
|
browser_bug495058.js \
|
||||||
browser_bug517902.js \
|
browser_bug517902.js \
|
||||||
|
browser_bug519216.js \
|
||||||
browser_bug520538.js \
|
browser_bug520538.js \
|
||||||
browser_bug521216.js \
|
browser_bug521216.js \
|
||||||
browser_bug537474.js \
|
browser_bug537474.js \
|
||||||
|
@ -38,11 +38,6 @@ var gFrontProgressListener = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gAllProgressListener = {
|
var gAllProgressListener = {
|
||||||
onProgressChange: function (aBrowser, aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress) {
|
|
||||||
},
|
|
||||||
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
var state = "onStateChange";
|
var state = "onStateChange";
|
||||||
info("AllProgress: " + state + " 0x" + aStateFlags.toString(16));
|
info("AllProgress: " + state + " 0x" + aStateFlags.toString(16));
|
||||||
|
@ -57,12 +57,7 @@ var gProgressListener = {
|
|||||||
ok(gBrowser.tabs.length == kURIs.length, "Correctly opened all expected tabs");
|
ok(gBrowser.tabs.length == kURIs.length, "Correctly opened all expected tabs");
|
||||||
finishTest();
|
finishTest();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
onProgressChange: function () {},
|
|
||||||
onLocationChange: function () {},
|
|
||||||
onStatusChange: function () {},
|
|
||||||
onSecurityChange: function () {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
|
48
browser/base/content/test/browser_bug519216.js
Normal file
48
browser/base/content/test/browser_bug519216.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.stop();
|
||||||
|
gBrowser.addProgressListener(progressListener1);
|
||||||
|
gBrowser.addProgressListener(progressListener2);
|
||||||
|
gBrowser.addProgressListener(progressListener3);
|
||||||
|
gBrowser.loadURI("data:text/plain,bug519216");
|
||||||
|
}
|
||||||
|
|
||||||
|
var calledListener1 = false;
|
||||||
|
var progressListener1 = {
|
||||||
|
onLocationChange: function onLocationChange() {
|
||||||
|
calledListener1 = true;
|
||||||
|
gBrowser.removeProgressListener(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var calledListener2 = false;
|
||||||
|
var progressListener2 = {
|
||||||
|
onLocationChange: function onLocationChange() {
|
||||||
|
ok(calledListener1, "called progressListener1 before progressListener2");
|
||||||
|
calledListener2 = true;
|
||||||
|
gBrowser.removeProgressListener(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var progressListener3 = {
|
||||||
|
onLocationChange: function onLocationChange() {
|
||||||
|
ok(calledListener2, "called progressListener2 before progressListener3");
|
||||||
|
gBrowser.removeProgressListener(this);
|
||||||
|
gBrowser.addProgressListener(progressListener4);
|
||||||
|
executeSoon(function () {
|
||||||
|
expectListener4 = true;
|
||||||
|
gBrowser.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var expectListener4 = false;
|
||||||
|
var progressListener4 = {
|
||||||
|
onLocationChange: function onLocationChange() {
|
||||||
|
ok(expectListener4, "didn't call progressListener4 for the first location change");
|
||||||
|
gBrowser.removeProgressListener(this);
|
||||||
|
gBrowser.addTab();
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
};
|
@ -35,13 +35,10 @@ var progressListener = {
|
|||||||
if (aBrowser == tab.linkedBrowser)
|
if (aBrowser == tab.linkedBrowser)
|
||||||
record(arguments.callee.name);
|
record(arguments.callee.name);
|
||||||
},
|
},
|
||||||
onProgressChange: function () {},
|
|
||||||
onSecurityChange: function () {},
|
|
||||||
onStateChange: function onStateChange(aBrowser) {
|
onStateChange: function onStateChange(aBrowser) {
|
||||||
if (aBrowser == tab.linkedBrowser)
|
if (aBrowser == tab.linkedBrowser)
|
||||||
record(arguments.callee.name);
|
record(arguments.callee.name);
|
||||||
},
|
},
|
||||||
onStatusChange: function () {},
|
|
||||||
onLinkIconAvailable: function onLinkIconAvailable(aBrowser) {
|
onLinkIconAvailable: function onLinkIconAvailable(aBrowser) {
|
||||||
if (aBrowser == tab.linkedBrowser)
|
if (aBrowser == tab.linkedBrowser)
|
||||||
record(arguments.callee.name);
|
record(arguments.callee.name);
|
||||||
|
@ -25,7 +25,7 @@ function test() {
|
|||||||
function doTest() {
|
function doTest() {
|
||||||
tabstrip.smoothScroll = false;
|
tabstrip.smoothScroll = false;
|
||||||
|
|
||||||
var tabMinWidth = gPrefService.getIntPref("browser.tabs.tabMinWidth");
|
var tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
|
||||||
var tabCountForOverflow = Math.ceil(width(tabstrip) / tabMinWidth * 3);
|
var tabCountForOverflow = Math.ceil(width(tabstrip) / tabMinWidth * 3);
|
||||||
while (tabContainer.childNodes.length < tabCountForOverflow)
|
while (tabContainer.childNodes.length < tabCountForOverflow)
|
||||||
gBrowser.addTab("about:blank", {skipAnimation: true});
|
gBrowser.addTab("about:blank", {skipAnimation: true});
|
||||||
|
@ -55,7 +55,7 @@ var SubscribeHandler = {
|
|||||||
this._feedWriter.close();
|
this._feedWriter.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
subscribe: function FH_subscribe() {
|
subscribe: function SH_subscribe() {
|
||||||
this._feedWriter.subscribe();
|
this._feedWriter.subscribe();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -95,21 +95,6 @@ var gTabsListener = {
|
|||||||
// Test finished. This will move to the next one.
|
// Test finished. This will move to the next one.
|
||||||
waitForFocus(gCurrentTest.finish, gBrowser.ownerDocument.defaultView);
|
waitForFocus(gCurrentTest.finish, gBrowser.ownerDocument.defaultView);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
onProgressChange: function(aBrowser, aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress) {
|
|
||||||
},
|
|
||||||
onStateChange: function(aBrowser, aWebProgress, aRequest,
|
|
||||||
aStateFlags, aStatus) {
|
|
||||||
},
|
|
||||||
onStatusChange: function(aBrowser, aWebProgress, aRequest,
|
|
||||||
aStatus, aMessage) {
|
|
||||||
},
|
|
||||||
onSecurityChange: function(aBrowser, aWebProgress, aRequest, aState) {
|
|
||||||
},
|
|
||||||
noLinkIconAvailable: function(aBrowser) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +141,6 @@
|
|||||||
label="&button.close.label;" accesskey="&button.close.accesskey;"/>
|
label="&button.close.label;" accesskey="&button.close.accesskey;"/>
|
||||||
#endif
|
#endif
|
||||||
</hbox>
|
</hbox>
|
||||||
<resizer dir="bottomend"/>
|
<resizer type="window" dir="bottomend"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</window>
|
</window>
|
||||||
|
@ -111,6 +111,6 @@
|
|||||||
label="&button.close.label;" accesskey="&button.close.accesskey;"/>
|
label="&button.close.label;" accesskey="&button.close.accesskey;"/>
|
||||||
#endif
|
#endif
|
||||||
</hbox>
|
</hbox>
|
||||||
<resizer dir="bottomend"/>
|
<resizer type="window" dir="bottomend"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</window>
|
</window>
|
||||||
|
@ -571,6 +571,17 @@ PrivateBrowsingService.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Image Cache
|
||||||
|
let (imageCache = Cc["@mozilla.org/image/cache;1"].
|
||||||
|
getService(Ci.imgICache)) {
|
||||||
|
try {
|
||||||
|
imageCache.clearCache(false); // true=chrome, false=content
|
||||||
|
} catch (ex) {
|
||||||
|
Cu.reportError("Exception thrown while clearing the image cache: " +
|
||||||
|
ex.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cookies
|
// Cookies
|
||||||
let (cm = Cc["@mozilla.org/cookiemanager;1"].
|
let (cm = Cc["@mozilla.org/cookiemanager;1"].
|
||||||
getService(Ci.nsICookieManager2)) {
|
getService(Ci.nsICookieManager2)) {
|
||||||
|
@ -92,11 +92,6 @@ function test() {
|
|||||||
Services.ww.registerNotification(observer);
|
Services.ww.registerNotification(observer);
|
||||||
|
|
||||||
gBrowser.addTabsProgressListener({
|
gBrowser.addTabsProgressListener({
|
||||||
onLocationChange: function() {},
|
|
||||||
onProgressChange: function() {},
|
|
||||||
onSecurityChange: function() {},
|
|
||||||
onStatusChange: function() {},
|
|
||||||
onRefreshAttempted: function() {},
|
|
||||||
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
|
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
|
||||||
Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
||||||
|
@ -83,8 +83,7 @@ function test() {
|
|||||||
let numTests = 4;
|
let numTests = 4;
|
||||||
let completedTests = 0;
|
let completedTests = 0;
|
||||||
|
|
||||||
// access the pref service just once
|
let tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
|
||||||
let tabMinWidth = gPrefService.getIntPref("browser.tabs.tabMinWidth");
|
|
||||||
|
|
||||||
function runTest(testNum, totalTabs, selectedTab, shownTabs, order) {
|
function runTest(testNum, totalTabs, selectedTab, shownTabs, order) {
|
||||||
let test = {
|
let test = {
|
||||||
|
@ -62,11 +62,7 @@ function test() {
|
|||||||
gBrowser.removeTabsProgressListener(this);
|
gBrowser.removeTabsProgressListener(this);
|
||||||
executeSoon(aSetStateCallback);
|
executeSoon(aSetStateCallback);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
onProgressChange: function () {},
|
|
||||||
onSecurityChange: function () {},
|
|
||||||
onStateChange: function () {},
|
|
||||||
onStatusChange: function () {}
|
|
||||||
});
|
});
|
||||||
ss.setBrowserState(JSON.stringify(aState));
|
ss.setBrowserState(JSON.stringify(aState));
|
||||||
}
|
}
|
||||||
@ -211,11 +207,7 @@ function test() {
|
|||||||
gBrowser.removeTabsProgressListener(this);
|
gBrowser.removeTabsProgressListener(this);
|
||||||
firstLocationChange();
|
firstLocationChange();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
onProgressChange: function () {},
|
|
||||||
onSecurityChange: function () {},
|
|
||||||
onStateChange: function () {},
|
|
||||||
onStatusChange: function () {}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function firstLocationChange() {
|
function firstLocationChange() {
|
||||||
|
@ -530,16 +530,6 @@ TabWindow.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
//// Browser progress listener
|
//// Browser progress listener
|
||||||
onLocationChange: function () {
|
|
||||||
},
|
|
||||||
onProgressChange: function () {
|
|
||||||
},
|
|
||||||
onSecurityChange: function () {
|
|
||||||
},
|
|
||||||
onStateChange: function () {
|
|
||||||
},
|
|
||||||
onStatusChange: function () {
|
|
||||||
},
|
|
||||||
onLinkIconAvailable: function (aBrowser, aIconURL) {
|
onLinkIconAvailable: function (aBrowser, aIconURL) {
|
||||||
let self = this;
|
let self = this;
|
||||||
getFaviconAsImage(aIconURL, function (img) {
|
getFaviconAsImage(aIconURL, function (img) {
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
<!ENTITY closeOtherTabs.accesskey "o">
|
<!ENTITY closeOtherTabs.accesskey "o">
|
||||||
<!ENTITY openTabInNewWindow.label "Open in a New Window">
|
<!ENTITY openTabInNewWindow.label "Open in a New Window">
|
||||||
<!ENTITY openTabInNewWindow.accesskey "W">
|
<!ENTITY openTabInNewWindow.accesskey "W">
|
||||||
|
<!ENTITY pinTab.label "Make into App Tab">
|
||||||
|
<!ENTITY pinTab.accesskey "p">
|
||||||
|
<!ENTITY unpinTab.label "Make into Normal Tab">
|
||||||
|
<!ENTITY unpinTab.accesskey "k">
|
||||||
<!ENTITY bookmarkThisTab.label "Bookmark This Tab">
|
<!ENTITY bookmarkThisTab.label "Bookmark This Tab">
|
||||||
<!ENTITY bookmarkThisTab.accesskey "B">
|
<!ENTITY bookmarkThisTab.accesskey "B">
|
||||||
<!ENTITY bookmarkAllTabs.label "Bookmark All Tabs…">
|
<!ENTITY bookmarkAllTabs.label "Bookmark All Tabs…">
|
||||||
|
@ -52,7 +52,7 @@ addonInstallManage.accesskey=O
|
|||||||
addonError-1=The add-on could not be downloaded because of a connection failure on #2.
|
addonError-1=The add-on could not be downloaded because of a connection failure on #2.
|
||||||
addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
|
addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
|
||||||
addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
|
addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
|
||||||
addonError-4=#1 could not be installed because Firefox cannot modify the needed file.
|
addonError-4=#1 could not be installed because #3 cannot modify the needed file.
|
||||||
addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
|
addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
|
||||||
addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
|
addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ browser/components/migration/Makefile
|
|||||||
browser/components/migration/public/Makefile
|
browser/components/migration/public/Makefile
|
||||||
browser/components/migration/src/Makefile
|
browser/components/migration/src/Makefile
|
||||||
browser/components/places/Makefile
|
browser/components/places/Makefile
|
||||||
browser/components/places/public/Makefile
|
|
||||||
browser/components/places/src/Makefile
|
browser/components/places/src/Makefile
|
||||||
browser/components/preferences/Makefile
|
browser/components/preferences/Makefile
|
||||||
browser/components/privatebrowsing/Makefile
|
browser/components/privatebrowsing/Makefile
|
||||||
|
@ -181,7 +181,7 @@ statusbarpanel#statusbar-display {
|
|||||||
position: relative !important;
|
position: relative !important;
|
||||||
background-color: -moz-dialog !important;
|
background-color: -moz-dialog !important;
|
||||||
}
|
}
|
||||||
#navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] ~ #TabsToolbar {
|
#navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] ~ #TabsToolbar:not([inFullscreen]) {
|
||||||
-moz-padding-start: 10em !important;
|
-moz-padding-start: 10em !important;
|
||||||
}
|
}
|
||||||
%ifdef WINSTRIPE_AERO
|
%ifdef WINSTRIPE_AERO
|
||||||
|
@ -40,12 +40,28 @@
|
|||||||
@import "chrome://global/skin/";
|
@import "chrome://global/skin/";
|
||||||
|
|
||||||
/* View buttons */
|
/* View buttons */
|
||||||
|
#viewGroup {
|
||||||
|
-moz-padding-start: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#viewGroup > radio {
|
#viewGroup > radio {
|
||||||
list-style-image: url("chrome://browser/skin/pageInfo.png");
|
list-style-image: url("chrome://browser/skin/pageInfo.png");
|
||||||
-moz-box-orient: vertical;
|
-moz-box-orient: vertical;
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
padding: 5px 3px 1px 3px;
|
padding: 5px 3px 1px 3px;
|
||||||
|
margin: 0 1px;
|
||||||
|
min-width: 4.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewGroup > radio:hover {
|
||||||
|
background-color: #E0E8F6;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewGroup > radio[selected="true"] {
|
||||||
|
background-color: #C1D2EE;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#topBar {
|
#topBar {
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
repo: f5ab154deef2ffa97f1b2139589ae4a1962090a4
|
repo: f5ab154deef2ffa97f1b2139589ae4a1962090a4
|
||||||
node: 3476582628db128ad061c30cab1a74a0c5d14b9b
|
node: 7ae0b4af32617677698f9de3ab76bcb154bbf085
|
||||||
|
@ -1402,7 +1402,7 @@ class Makefile(object):
|
|||||||
Inform the makefile of a target which is a candidate for being the default target,
|
Inform the makefile of a target which is a candidate for being the default target,
|
||||||
if there isn't already a default target.
|
if there isn't already a default target.
|
||||||
"""
|
"""
|
||||||
if self.defaulttarget is None:
|
if self.defaulttarget is None and t != '.PHONY':
|
||||||
self.defaulttarget = t
|
self.defaulttarget = t
|
||||||
|
|
||||||
def getpatternvariables(self, pattern):
|
def getpatternvariables(self, pattern):
|
||||||
|
@ -284,7 +284,7 @@ def ifeq(d, offset):
|
|||||||
if token == '(':
|
if token == '(':
|
||||||
arg1, t, offset = parsemakesyntax(d, offset, (',',), itermakefilechars)
|
arg1, t, offset = parsemakesyntax(d, offset, (',',), itermakefilechars)
|
||||||
if t is None:
|
if t is None:
|
||||||
raise SyntaxError("Expected two arguments in conditional", d.getloc(offset))
|
raise SyntaxError("Expected two arguments in conditional", d.getloc(d.lend))
|
||||||
|
|
||||||
arg1.rstrip()
|
arg1.rstrip()
|
||||||
|
|
||||||
@ -604,6 +604,9 @@ class ParseStackFrame(object):
|
|||||||
self.function = function
|
self.function = function
|
||||||
self.loc = loc
|
self.loc = loc
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "<state=%i expansion=%s tokenlist=%s openbrace=%s closebrace=%s>" % (self.parsestate, self.expansion, self.tokenlist, self.openbrace, self.closebrace)
|
||||||
|
|
||||||
_matchingbrace = {
|
_matchingbrace = {
|
||||||
'(': ')',
|
'(': ')',
|
||||||
'{': '}',
|
'{': '}',
|
||||||
@ -689,7 +692,7 @@ def parsemakesyntax(d, offset, stopon, iterfunc):
|
|||||||
stacktop.expansion.appendstr(token)
|
stacktop.expansion.appendstr(token)
|
||||||
stacktop = ParseStackFrame(_PARSESTATE_PARENMATCH, stacktop,
|
stacktop = ParseStackFrame(_PARSESTATE_PARENMATCH, stacktop,
|
||||||
stacktop.expansion,
|
stacktop.expansion,
|
||||||
(token, stacktop.closebrace),
|
(token, stacktop.closebrace, '$'),
|
||||||
openbrace=token, closebrace=stacktop.closebrace, loc=d.getloc(tokenoffset))
|
openbrace=token, closebrace=stacktop.closebrace, loc=d.getloc(tokenoffset))
|
||||||
elif parsestate == _PARSESTATE_PARENMATCH:
|
elif parsestate == _PARSESTATE_PARENMATCH:
|
||||||
assert token == stacktop.closebrace
|
assert token == stacktop.closebrace
|
||||||
|
@ -3,6 +3,8 @@ test: VAR = value
|
|||||||
%.do:
|
%.do:
|
||||||
@echo TEST-FAIL: ran target "$@", should have run "all"
|
@echo TEST-FAIL: ran target "$@", should have run "all"
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo TEST-PASS: the default target is all
|
@echo TEST-PASS: the default target is all
|
||||||
|
|
||||||
|
6
build/pymake/tests/if-syntaxerr.mk
Normal file
6
build/pymake/tests/if-syntaxerr.mk
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#T returncode: 2
|
||||||
|
|
||||||
|
ifeq ($(FOO,VAR))
|
||||||
|
all:
|
||||||
|
@echo TEST_FAIL
|
||||||
|
endif
|
@ -1,5 +1,5 @@
|
|||||||
$(shell \
|
$(shell \
|
||||||
if test ! -f include-dynamic.inc; then \
|
if ! test -f include-dynamic.inc; then \
|
||||||
echo "TESTVAR = oldval" > include-dynamic.inc; \
|
echo "TESTVAR = oldval" > include-dynamic.inc; \
|
||||||
sleep 2; \
|
sleep 2; \
|
||||||
echo "TESTVAR = newval" > include-dynamic.inc.in; \
|
echo "TESTVAR = newval" > include-dynamic.inc.in; \
|
||||||
|
9
build/pymake/tests/path-length.mk
Normal file
9
build/pymake/tests/path-length.mk
Normal file
File diff suppressed because one or more lines are too long
@ -78,7 +78,7 @@ nsNullPrincipal::Release()
|
|||||||
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
||||||
NS_LOG_RELEASE(this, count, "nsNullPrincipal");
|
NS_LOG_RELEASE(this, count, "nsNullPrincipal");
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
NS_DELETEXPCOM(this);
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -166,7 +166,7 @@ nsPrincipal::Release()
|
|||||||
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
||||||
NS_LOG_RELEASE(this, count, "nsPrincipal");
|
NS_LOG_RELEASE(this, count, "nsPrincipal");
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
NS_DELETEXPCOM(this);
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -75,7 +75,7 @@ nsSystemPrincipal::Release()
|
|||||||
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
|
||||||
NS_LOG_RELEASE(this, count, "nsSystemPrincipal");
|
NS_LOG_RELEASE(this, count, "nsSystemPrincipal");
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
NS_DELETEXPCOM(this);
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -46,6 +46,7 @@ MODULE = chrome
|
|||||||
LIBRARY_NAME = chrome_s
|
LIBRARY_NAME = chrome_s
|
||||||
LIBXUL_LIBRARY = 1
|
LIBXUL_LIBRARY = 1
|
||||||
FORCE_STATIC_LIB = 1
|
FORCE_STATIC_LIB = 1
|
||||||
|
FORCE_USE_PIC = 1
|
||||||
|
|
||||||
EXPORTS_NAMESPACES = mozilla/chrome
|
EXPORTS_NAMESPACES = mozilla/chrome
|
||||||
|
|
||||||
|
@ -51,10 +51,12 @@ function do_run_test()
|
|||||||
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
|
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
|
||||||
getService(Ci.nsIChromeRegistry);
|
getService(Ci.nsIChromeRegistry);
|
||||||
|
|
||||||
var runtime = Components.classes["@mozilla.org/xre/app-info;1"]
|
// If we don't have libxul or e10s then we don't have process separation, so
|
||||||
.getService(Components.interfaces.nsIXULRuntime);
|
// we don't need to worry about checking for new chrome.
|
||||||
if (runtime.processType ==
|
var appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||||
Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
|
if (!appInfo ||
|
||||||
|
(appInfo.getService(Ci.nsIXULRuntime).processType ==
|
||||||
|
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT)) {
|
||||||
cr.checkForNewChrome();
|
cr.checkForNewChrome();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#line 2 "nsStaticComponents.cpp.in"
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
@ -40,21 +41,16 @@
|
|||||||
|
|
||||||
#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT 1
|
#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT 1
|
||||||
|
|
||||||
#include "nsIGenericFactory.h"
|
#include "mozilla/ModuleUtils.h"
|
||||||
#include "nsXPCOM.h"
|
#include "nsXPCOM.h"
|
||||||
#include "nsMemory.h"
|
#include "nsMemory.h"
|
||||||
#include "nsStaticComponents.h"
|
#include "nsStaticComponents.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a unique NSGetModule entry point for a generic module.
|
|
||||||
*/
|
|
||||||
#define NSGETMODULE(_name) _name##_NSGetModule
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare an NSGetModule() routine for a generic module.
|
* Declare an NSGetModule() routine for a generic module.
|
||||||
*/
|
*/
|
||||||
#define MODULE(_name) \
|
#define MODULE(_name) \
|
||||||
NSGETMODULE_ENTRY_POINT(_name) (nsIComponentManager*, nsIFile*, nsIModule**);
|
NSMODULE_DECL(_name);
|
||||||
|
|
||||||
%MODULE_LIST%
|
%MODULE_LIST%
|
||||||
#line 57 "nsStaticComponents.cpp.in"
|
#line 57 "nsStaticComponents.cpp.in"
|
||||||
@ -62,15 +58,16 @@ NSGETMODULE_ENTRY_POINT(_name) (nsIComponentManager*, nsIFile*, nsIModule**);
|
|||||||
#undef MODULE
|
#undef MODULE
|
||||||
|
|
||||||
|
|
||||||
#define MODULE(_name) { #_name, NSGETMODULE(_name) },
|
#define MODULE(_name) \
|
||||||
|
NSMODULE_NAME(_name),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The nsStaticModuleInfo
|
* The nsStaticModuleInfo
|
||||||
*/
|
*/
|
||||||
static nsStaticModuleInfo const gStaticModuleInfo[] = {
|
static const mozilla::Module *const kStaticModules[] = {
|
||||||
%MODULE_LIST%
|
%MODULE_LIST%
|
||||||
#line 69 "nsStaticComponents.cpp.in"
|
#line 70 "nsStaticComponents.cpp.in"
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
nsStaticModuleInfo const *const kPStaticModules = gStaticModuleInfo;
|
mozilla::Module const *const *const kPStaticModules = kStaticModules;
|
||||||
PRUint32 const kStaticModuleCount = NS_ARRAY_LENGTH(gStaticModuleInfo);
|
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
$found = 1;
|
$found = 1;
|
||||||
|
|
||||||
# GLOBALS
|
# GLOBALS
|
||||||
$SEP = 0; # the paltform independent path separator
|
$SEP = 0; # the platform independent path separator
|
||||||
$CFG = 0; # the value of the -cfg flag
|
$CFG = 0; # the value of the -cfg flag
|
||||||
|
|
||||||
# determine the path separator
|
# determine the path separator
|
||||||
|
@ -168,6 +168,7 @@ xpcshell-tests:
|
|||||||
-I$(topsrcdir)/build \
|
-I$(topsrcdir)/build \
|
||||||
$(testxpcsrcdir)/runxpcshelltests.py \
|
$(testxpcsrcdir)/runxpcshelltests.py \
|
||||||
--symbols-path=$(DIST)/crashreporter-symbols \
|
--symbols-path=$(DIST)/crashreporter-symbols \
|
||||||
|
$(EXTRA_TEST_ARGS) \
|
||||||
$(DIST)/bin/xpcshell \
|
$(DIST)/bin/xpcshell \
|
||||||
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
|
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
|
||||||
|
|
||||||
@ -193,6 +194,8 @@ check-one:
|
|||||||
--symbols-path=$(DIST)/crashreporter-symbols \
|
--symbols-path=$(DIST)/crashreporter-symbols \
|
||||||
--test-path=$(SOLO_FILE) \
|
--test-path=$(SOLO_FILE) \
|
||||||
--profile-name=$(MOZ_APP_NAME) \
|
--profile-name=$(MOZ_APP_NAME) \
|
||||||
|
--verbose \
|
||||||
|
$(EXTRA_TEST_ARGS) \
|
||||||
$(DIST)/bin/xpcshell \
|
$(DIST)/bin/xpcshell \
|
||||||
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
|
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
|
||||||
|
|
||||||
@ -2291,3 +2294,6 @@ CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
|
|||||||
|
|
||||||
libs export libs::
|
libs export libs::
|
||||||
$(CHECK_FROZEN_VARIABLES)
|
$(CHECK_FROZEN_VARIABLES)
|
||||||
|
|
||||||
|
default::
|
||||||
|
if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
|
||||||
|
40
configure.in
40
configure.in
@ -1538,7 +1538,7 @@ x86_64 | ia64)
|
|||||||
CPU_ARCH="$OS_TEST"
|
CPU_ARCH="$OS_TEST"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
arm)
|
arm*)
|
||||||
CPU_ARCH=arm
|
CPU_ARCH=arm
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1567,8 +1567,8 @@ if test "$GNU_CC"; then
|
|||||||
ASFLAGS="$ASFLAGS -fPIC"
|
ASFLAGS="$ASFLAGS -fPIC"
|
||||||
_MOZ_RTTI_FLAGS_ON=${_COMPILER_PREFIX}-frtti
|
_MOZ_RTTI_FLAGS_ON=${_COMPILER_PREFIX}-frtti
|
||||||
_MOZ_RTTI_FLAGS_OFF=${_COMPILER_PREFIX}-fno-rtti
|
_MOZ_RTTI_FLAGS_OFF=${_COMPILER_PREFIX}-fno-rtti
|
||||||
_MOZ_EXCEPTIONS_FLAGS_ON='-fhandle-exceptions'
|
_MOZ_EXCEPTIONS_FLAGS_ON='-fexceptions'
|
||||||
_MOZ_EXCEPTIONS_FLAGS_OFF='-fno-handle-exceptions'
|
_MOZ_EXCEPTIONS_FLAGS_OFF='-fno-exceptions'
|
||||||
|
|
||||||
# Turn on GNU specific features
|
# Turn on GNU specific features
|
||||||
# -Wall - turn on all warnings
|
# -Wall - turn on all warnings
|
||||||
@ -2539,8 +2539,8 @@ ia64*-hpux*)
|
|||||||
USE_PTHREADS=1
|
USE_PTHREADS=1
|
||||||
_PEDANTIC=
|
_PEDANTIC=
|
||||||
LIBS="$LIBS -lsocket -lstdc++"
|
LIBS="$LIBS -lsocket -lstdc++"
|
||||||
_DEFINES_CFLAGS='-Wp,-include -Wp,$(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT -D_POSIX_C_SOURCE=199506'
|
_DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT -D_POSIX_C_SOURCE=199506'
|
||||||
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -Wp,-include -Wp,$(DEPTH)/mozilla-config.h -D_POSIX_C_SOURCE=199506'
|
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h -D_POSIX_C_SOURCE=199506'
|
||||||
if test "$with_x" != "yes"
|
if test "$with_x" != "yes"
|
||||||
then
|
then
|
||||||
_PLATFORM_DEFAULT_TOOLKIT="photon"
|
_PLATFORM_DEFAULT_TOOLKIT="photon"
|
||||||
@ -4024,32 +4024,6 @@ EOF
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
dnl ========================================================
|
|
||||||
dnl By default, turn rtti and exceptions off on g++/egcs
|
|
||||||
dnl ========================================================
|
|
||||||
if test "$GNU_CXX"; then
|
|
||||||
|
|
||||||
AC_MSG_CHECKING(for C++ exceptions flag)
|
|
||||||
|
|
||||||
dnl They changed -f[no-]handle-exceptions to -f[no-]exceptions in g++ 2.8
|
|
||||||
AC_CACHE_VAL(ac_cv_cxx_exceptions_flags,
|
|
||||||
[echo "int main() { return 0; }" | cat > conftest.C
|
|
||||||
|
|
||||||
${CXX-g++} ${CXXFLAGS} -c -fno-handle-exceptions conftest.C > conftest.out 2>&1
|
|
||||||
|
|
||||||
if egrep "warning.*renamed" conftest.out >/dev/null; then
|
|
||||||
ac_cv_cxx_exceptions_flags=${_COMPILER_PREFIX}-fno-exceptions
|
|
||||||
else
|
|
||||||
ac_cv_cxx_exceptions_flags=${_COMPILER_PREFIX}-fno-handle-exceptions
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f conftest*])
|
|
||||||
|
|
||||||
AC_MSG_RESULT($ac_cv_cxx_exceptions_flags)
|
|
||||||
_MOZ_EXCEPTIONS_FLAGS_OFF=$ac_cv_cxx_exceptions_flags
|
|
||||||
_MOZ_EXCEPTIONS_FLAGS_ON=`echo $ac_cv_cxx_exceptions_flags | sed 's|no-||'`
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl Put your C++ language/feature checks below
|
dnl Put your C++ language/feature checks below
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
@ -6005,7 +5979,7 @@ if test -n "$MOZ_SYDNEYAUDIO"; then
|
|||||||
linux*)
|
linux*)
|
||||||
PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
|
PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
|
||||||
[echo "$MOZ_ALSA_PKG_ERRORS"
|
[echo "$MOZ_ALSA_PKG_ERRORS"
|
||||||
AC_MSG_ERROR([Need alsa for Ogg or Wave decoding on Linux. Disable with --disable-ogg --disable-wave. (On Ubuntu, you might try installing the package libasound2-dev.)])])
|
AC_MSG_ERROR([Need alsa for Ogg, Wave or WebM decoding on Linux. Disable with --disable-ogg --disable-wave --disable-webm. (On Ubuntu, you might try installing the package libasound2-dev.)])])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
@ -7977,7 +7951,7 @@ if test "$_cpp_md_flag"; then
|
|||||||
if test "$OS_ARCH" = "OpenVMS"; then
|
if test "$OS_ARCH" = "OpenVMS"; then
|
||||||
_DEPEND_CFLAGS='$(subst =, ,$(filter-out %/.pp,-MM=-MD=-MF=$(MDDEPDIR)/$(basename $(@F)).pp))'
|
_DEPEND_CFLAGS='$(subst =, ,$(filter-out %/.pp,-MM=-MD=-MF=$(MDDEPDIR)/$(basename $(@F)).pp))'
|
||||||
else
|
else
|
||||||
_DEPEND_CFLAGS='$(filter-out %/.pp,-Wp,-MD,$(MDDEPDIR)/$(basename $(@F)).pp)'
|
_DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(basename $(@F)).pp)'
|
||||||
fi
|
fi
|
||||||
dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
|
dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
|
||||||
if test "$SOLARIS_SUNPRO_CC"; then
|
if test "$SOLARIS_SUNPRO_CC"; then
|
||||||
|
@ -130,6 +130,7 @@ class nsIMIMEHeaderParam;
|
|||||||
class nsIObserver;
|
class nsIObserver;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsIChannel;
|
class nsIChannel;
|
||||||
|
struct nsIntMargin;
|
||||||
|
|
||||||
#ifndef have_PrefChangedFunc_typedef
|
#ifndef have_PrefChangedFunc_typedef
|
||||||
typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *);
|
typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *);
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#define nsCopySupport_h__
|
#define nsCopySupport_h__
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
#include "nsINode.h"
|
||||||
|
|
||||||
class nsISelection;
|
class nsISelection;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
@ -47,7 +48,6 @@ class nsIContent;
|
|||||||
class nsITransferable;
|
class nsITransferable;
|
||||||
class nsACString;
|
class nsACString;
|
||||||
class nsAString;
|
class nsAString;
|
||||||
class nsIDOMNode;
|
|
||||||
class nsIPresShell;
|
class nsIPresShell;
|
||||||
|
|
||||||
class nsCopySupport
|
class nsCopySupport
|
||||||
@ -69,10 +69,14 @@ class nsCopySupport
|
|||||||
|
|
||||||
// Get the selection as a transferable. Similar to HTMLCopy except does
|
// Get the selection as a transferable. Similar to HTMLCopy except does
|
||||||
// not deal with the clipboard.
|
// not deal with the clipboard.
|
||||||
static nsresult GetTransferableForSelection(nsISelection * aSelection,
|
static nsresult GetTransferableForSelection(nsISelection* aSelection,
|
||||||
nsIDocument * aDocument,
|
nsIDocument* aDocument,
|
||||||
nsITransferable ** aTransferable);
|
nsITransferable** aTransferable);
|
||||||
|
|
||||||
|
// Same as GetTransferableForSelection, but doesn't skip invisible content.
|
||||||
|
static nsresult GetTransferableForNode(nsINode* aNode,
|
||||||
|
nsIDocument* aDoc,
|
||||||
|
nsITransferable** aTransferable);
|
||||||
/**
|
/**
|
||||||
* Retrieve the selection for the given document. If the current focus
|
* Retrieve the selection for the given document. If the current focus
|
||||||
* within the document has its own selection, aSelection will be set to it
|
* within the document has its own selection, aSelection will be set to it
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
#include "nsChannelProperties.h"
|
#include "nsChannelProperties.h"
|
||||||
|
|
||||||
/* Keeps track of whether or not CSP is enabled */
|
/* Keeps track of whether or not CSP is enabled */
|
||||||
static PRBool gCSPEnabled = PR_TRUE;
|
PRBool CSPService::sCSPEnabled = PR_TRUE;
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
static PRLogModuleInfo* gCspPRLog;
|
static PRLogModuleInfo* gCspPRLog;
|
||||||
@ -63,7 +63,7 @@ static PRLogModuleInfo* gCspPRLog;
|
|||||||
|
|
||||||
CSPService::CSPService()
|
CSPService::CSPService()
|
||||||
{
|
{
|
||||||
nsContentUtils::AddBoolPrefVarCache("security.csp.enable", &gCSPEnabled);
|
nsContentUtils::AddBoolPrefVarCache("security.csp.enable", &sCSPEnabled);
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
if (!gCspPRLog)
|
if (!gCspPRLog)
|
||||||
@ -102,7 +102,7 @@ CSPService::ShouldLoad(PRUint32 aContentType,
|
|||||||
*aDecision = nsIContentPolicy::ACCEPT;
|
*aDecision = nsIContentPolicy::ACCEPT;
|
||||||
|
|
||||||
// No need to continue processing if CSP is disabled
|
// No need to continue processing if CSP is disabled
|
||||||
if (!gCSPEnabled)
|
if (!sCSPEnabled)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// find the principal of the document that initiated this request and see
|
// find the principal of the document that initiated this request and see
|
||||||
@ -160,7 +160,7 @@ CSPService::ShouldProcess(PRUint32 aContentType,
|
|||||||
*aDecision = nsIContentPolicy::ACCEPT;
|
*aDecision = nsIContentPolicy::ACCEPT;
|
||||||
|
|
||||||
// No need to continue processing if CSP is disabled
|
// No need to continue processing if CSP is disabled
|
||||||
if (!gCSPEnabled)
|
if (!sCSPEnabled)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// find the nsDocument that initiated this request and see if it has a
|
// find the nsDocument that initiated this request and see if it has a
|
||||||
|
@ -52,7 +52,8 @@ public:
|
|||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSICONTENTPOLICY
|
NS_DECL_NSICONTENTPOLICY
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
|
|
||||||
CSPService();
|
CSPService();
|
||||||
virtual ~CSPService();
|
virtual ~CSPService();
|
||||||
|
static PRBool sCSPEnabled;
|
||||||
};
|
};
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "nsChannelPolicy.h"
|
#include "nsChannelPolicy.h"
|
||||||
|
|
||||||
nsChannelPolicy::nsChannelPolicy()
|
nsChannelPolicy::nsChannelPolicy()
|
||||||
|
: mLoadType(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,6 @@
|
|||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsIDocShellTreeItem.h"
|
#include "nsIDocShellTreeItem.h"
|
||||||
#include "nsRange.h"
|
|
||||||
#include "nsIWebBrowserPersist.h"
|
#include "nsIWebBrowserPersist.h"
|
||||||
#include "nsEscape.h"
|
#include "nsEscape.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
@ -92,9 +91,7 @@
|
|||||||
#define kHTMLContext "text/_moz_htmlcontext"
|
#define kHTMLContext "text/_moz_htmlcontext"
|
||||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||||
|
|
||||||
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
|
// if aNode is null, use the selection from the window
|
||||||
|
|
||||||
// if inNode is null, use the selection from the window
|
|
||||||
static nsresult
|
static nsresult
|
||||||
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
|
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
|
||||||
nsIContent* aNode,
|
nsIContent* aNode,
|
||||||
@ -108,25 +105,15 @@ GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
|
|||||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsISelection> selection;
|
if (aNode) {
|
||||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
|
rv = nsCopySupport::GetTransferableForNode(aNode, doc, aTransferable);
|
||||||
if (node) {
|
|
||||||
// Make a temporary selection with this node in a single range.
|
|
||||||
rv = NS_NewDomSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
nsCOMPtr<nsIDOMRange> range;
|
|
||||||
rv = NS_NewRange(getter_AddRefs(range));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = range->SelectNode(node);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = selection->AddRange(range);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
} else {
|
} else {
|
||||||
|
nsCOMPtr<nsISelection> selection;
|
||||||
aWindow->GetSelection(getter_AddRefs(selection));
|
aWindow->GetSelection(getter_AddRefs(selection));
|
||||||
|
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
|
||||||
|
aTransferable);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
|
|
||||||
aTransferable);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -424,7 +411,6 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
PRBool* aCanDrag,
|
PRBool* aCanDrag,
|
||||||
|
@ -2415,7 +2415,8 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
|||||||
NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
|
NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
|
||||||
NS_PRECONDITION(aRequest, "Null out param");
|
NS_PRECONDITION(aRequest, "Null out param");
|
||||||
|
|
||||||
if (!sImgLoader) {
|
imgILoader* imgLoader = GetImgLoader();
|
||||||
|
if (!imgLoader) {
|
||||||
// nothing we can do here
|
// nothing we can do here
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -2444,17 +2445,17 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
|||||||
|
|
||||||
// XXXbz using "documentURI" for the initialDocumentURI is not quite
|
// XXXbz using "documentURI" for the initialDocumentURI is not quite
|
||||||
// right, but the best we can do here...
|
// right, but the best we can do here...
|
||||||
return sImgLoader->LoadImage(aURI, /* uri to load */
|
return imgLoader->LoadImage(aURI, /* uri to load */
|
||||||
documentURI, /* initialDocumentURI */
|
documentURI, /* initialDocumentURI */
|
||||||
aReferrer, /* referrer */
|
aReferrer, /* referrer */
|
||||||
loadGroup, /* loadgroup */
|
loadGroup, /* loadgroup */
|
||||||
aObserver, /* imgIDecoderObserver */
|
aObserver, /* imgIDecoderObserver */
|
||||||
aLoadingDocument, /* uniquification key */
|
aLoadingDocument, /* uniquification key */
|
||||||
aLoadFlags, /* load flags */
|
aLoadFlags, /* load flags */
|
||||||
nsnull, /* cache key */
|
nsnull, /* cache key */
|
||||||
nsnull, /* existing request*/
|
nsnull, /* existing request*/
|
||||||
channelPolicy, /* CSP info */
|
channelPolicy, /* CSP info */
|
||||||
aRequest);
|
aRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "nsXPCOM.h"
|
#include "nsXPCOM.h"
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
#include "nsIDOMRange.h"
|
#include "nsIDOMRange.h"
|
||||||
|
#include "nsRange.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
@ -78,6 +79,8 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsContentCID.h"
|
#include "nsContentCID.h"
|
||||||
|
|
||||||
|
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
|
||||||
|
|
||||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||||
@ -100,7 +103,7 @@ static nsresult AppendDOMNode(nsITransferable *aTransferable,
|
|||||||
static nsresult
|
static nsresult
|
||||||
SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
||||||
PRBool doPutOnClipboard, PRInt16 aClipboardID,
|
PRBool doPutOnClipboard, PRInt16 aClipboardID,
|
||||||
nsITransferable ** aTransferable)
|
PRUint32 aFlags, nsITransferable ** aTransferable)
|
||||||
{
|
{
|
||||||
// Clear the output parameter for the transferable, if provided.
|
// Clear the output parameter for the transferable, if provided.
|
||||||
if (aTransferable) {
|
if (aTransferable) {
|
||||||
@ -135,9 +138,8 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
|||||||
// we want preformatted for the case where the selection is inside input/textarea
|
// we want preformatted for the case where the selection is inside input/textarea
|
||||||
// and we don't want pretty printing for others cases, to not have additionnal
|
// and we don't want pretty printing for others cases, to not have additionnal
|
||||||
// line breaks which are then converted into spaces by the htmlConverter (see bug #524975)
|
// line breaks which are then converted into spaces by the htmlConverter (see bug #524975)
|
||||||
PRUint32 flags = nsIDocumentEncoder::OutputPreformatted
|
PRUint32 flags = aFlags | nsIDocumentEncoder::OutputPreformatted
|
||||||
| nsIDocumentEncoder::OutputRaw
|
| nsIDocumentEncoder::OutputRaw;
|
||||||
| nsIDocumentEncoder::SkipInvisibleContent;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
||||||
NS_ASSERTION(domDoc, "Need a document");
|
NS_ASSERTION(domDoc, "Need a document");
|
||||||
@ -178,7 +180,7 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
|||||||
|
|
||||||
mimeType.AssignLiteral(kHTMLMime);
|
mimeType.AssignLiteral(kHTMLMime);
|
||||||
|
|
||||||
flags = nsIDocumentEncoder::SkipInvisibleContent;
|
flags = aFlags;
|
||||||
|
|
||||||
rv = docEncoder->Init(domDoc, mimeType, flags);
|
rv = docEncoder->Init(domDoc, mimeType, flags);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
@ -279,17 +281,47 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
|
nsresult
|
||||||
|
nsCopySupport::HTMLCopy(nsISelection* aSel, nsIDocument* aDoc,
|
||||||
|
PRInt16 aClipboardID)
|
||||||
{
|
{
|
||||||
return SelectionCopyHelper(aSel, aDoc, PR_TRUE, aClipboardID, nsnull);
|
return SelectionCopyHelper(aSel, aDoc, PR_TRUE, aClipboardID,
|
||||||
|
nsIDocumentEncoder::SkipInvisibleContent,
|
||||||
|
nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsCopySupport::GetTransferableForSelection(nsISelection * aSel,
|
nsCopySupport::GetTransferableForSelection(nsISelection* aSel,
|
||||||
nsIDocument * aDoc,
|
nsIDocument* aDoc,
|
||||||
nsITransferable ** aTransferable)
|
nsITransferable** aTransferable)
|
||||||
{
|
{
|
||||||
return SelectionCopyHelper(aSel, aDoc, PR_FALSE, 0, aTransferable);
|
return SelectionCopyHelper(aSel, aDoc, PR_FALSE, 0,
|
||||||
|
nsIDocumentEncoder::SkipInvisibleContent,
|
||||||
|
aTransferable);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsCopySupport::GetTransferableForNode(nsINode* aNode,
|
||||||
|
nsIDocument* aDoc,
|
||||||
|
nsITransferable** aTransferable)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISelection> selection;
|
||||||
|
// Make a temporary selection with aNode in a single range.
|
||||||
|
nsresult rv = NS_NewDomSelection(getter_AddRefs(selection));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsCOMPtr<nsIDOMRange> range;
|
||||||
|
rv = NS_NewRange(getter_AddRefs(range));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
|
||||||
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||||
|
rv = range->SelectNode(node);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = selection->AddRange(range);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
// It's not the primary selection - so don't skip invisible content.
|
||||||
|
PRUint32 flags = 0;
|
||||||
|
return SelectionCopyHelper(selection, aDoc, PR_FALSE, 0, flags,
|
||||||
|
aTransferable);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsCopySupport::DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
|
nsresult nsCopySupport::DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
|
||||||
|
@ -195,6 +195,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||||||
|
|
||||||
// FOR CSP (autogenerated by xpidl)
|
// FOR CSP (autogenerated by xpidl)
|
||||||
#include "nsIContentSecurityPolicy.h"
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
#include "nsCSPService.h"
|
||||||
#include "nsHTMLStyleSheet.h"
|
#include "nsHTMLStyleSheet.h"
|
||||||
#include "nsHTMLCSSStyleSheet.h"
|
#include "nsHTMLCSSStyleSheet.h"
|
||||||
|
|
||||||
@ -202,9 +203,6 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
|
||||||
/* Keeps track of whether or not CSP is enabled */
|
|
||||||
static PRBool gCSPEnabled = PR_TRUE;
|
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
static PRLogModuleInfo* gDocumentLeakPRLog;
|
static PRLogModuleInfo* gDocumentLeakPRLog;
|
||||||
static PRLogModuleInfo* gCspPRLog;
|
static PRLogModuleInfo* gCspPRLog;
|
||||||
@ -1409,8 +1407,6 @@ nsDocument::nsDocument(const char* aContentType)
|
|||||||
gCspPRLog = PR_NewLogModule("CSP");
|
gCspPRLog = PR_NewLogModule("CSP");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsContentUtils::AddBoolPrefVarCache("security.csp.enable", &gCSPEnabled);
|
|
||||||
|
|
||||||
// Start out mLastStyleSheetSet as null, per spec
|
// Start out mLastStyleSheetSet as null, per spec
|
||||||
SetDOMStringToNull(mLastStyleSheetSet);
|
SetDOMStringToNull(mLastStyleSheetSet);
|
||||||
}
|
}
|
||||||
@ -2175,7 +2171,7 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
|||||||
nsresult
|
nsresult
|
||||||
nsDocument::InitCSP()
|
nsDocument::InitCSP()
|
||||||
{
|
{
|
||||||
if (gCSPEnabled) {
|
if (CSPService::sCSPEnabled) {
|
||||||
nsAutoString cspHeaderValue;
|
nsAutoString cspHeaderValue;
|
||||||
nsAutoString cspROHeaderValue;
|
nsAutoString cspROHeaderValue;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ bool SendSyncMessageToParent(void* aCallbackData,
|
|||||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||||
asyncMessages.SwapElements(tabChild->mASyncMessages);
|
asyncMessages.SwapElements(tabChild->mASyncMessages);
|
||||||
PRUint32 len = asyncMessages.Length();
|
PRUint32 len = asyncMessages.Length();
|
||||||
for (PRInt32 i = 0; i < len; ++i) {
|
for (PRUint32 i = 0; i < len; ++i) {
|
||||||
nsCOMPtr<nsIRunnable> async = asyncMessages[i];
|
nsCOMPtr<nsIRunnable> async = asyncMessages[i];
|
||||||
async->Run();
|
async->Run();
|
||||||
}
|
}
|
||||||
@ -286,8 +286,9 @@ nsInProcessTabChildGlobal::InitTabChildGlobal()
|
|||||||
|
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
|
xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
|
||||||
NS_GET_IID(nsISupports), flags,
|
NS_GET_IID(nsISupports),
|
||||||
getter_AddRefs(mGlobal));
|
GetPrincipal(), EmptyCString(),
|
||||||
|
flags, getter_AddRefs(mGlobal));
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
JSObject* global = nsnull;
|
JSObject* global = nsnull;
|
||||||
|
@ -1360,8 +1360,7 @@ nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
|
|||||||
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
|
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
|
||||||
|
|
||||||
if (httpChannel) {
|
if (httpChannel) {
|
||||||
nsHeaderVisitor *visitor = nsnull;
|
nsHeaderVisitor *visitor = new nsHeaderVisitor();
|
||||||
NS_NEWXPCOM(visitor, nsHeaderVisitor);
|
|
||||||
if (!visitor)
|
if (!visitor)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
NS_ADDREF(visitor);
|
NS_ADDREF(visitor);
|
||||||
|
@ -402,6 +402,7 @@ _TEST_FILES2 = \
|
|||||||
test_websocket.html \
|
test_websocket.html \
|
||||||
file_websocket_wsh.py \
|
file_websocket_wsh.py \
|
||||||
file_websocket_http_resource.txt \
|
file_websocket_http_resource.txt \
|
||||||
|
test_bug574596.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# This test fails on the Mac for some reason
|
# This test fails on the Mac for some reason
|
||||||
|
86
content/base/test/test_bug574596.html
Normal file
86
content/base/test/test_bug574596.html
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=574596
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 574596</title>
|
||||||
|
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=574596">Mozilla Bug 574596</a>
|
||||||
|
<style type="text/css">
|
||||||
|
#link1 a { -moz-user-select:none; }
|
||||||
|
</style>
|
||||||
|
<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>
|
||||||
|
<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 574596 **/
|
||||||
|
|
||||||
|
function ignoreFunc(actualData, expectedData) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dragLinkText = [[
|
||||||
|
{ type:"text/x-moz-url", data:"", eqTest:ignoreFunc },
|
||||||
|
{ type:"text/x-moz-url-data", data:"http://www.mozilla.org/" },
|
||||||
|
{ type:"text/x-moz-url-desc", data:"link1" },
|
||||||
|
{ type:"text/uri-list", data:"http://www.mozilla.org/" },
|
||||||
|
{ type:"text/_moz_htmlcontext", data:"", eqTest:ignoreFunc },
|
||||||
|
{ type:"text/_moz_htmlinfo", data:"", eqTest:ignoreFunc },
|
||||||
|
{ type:"text/html", data:'<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>' },
|
||||||
|
{ type:"text/plain", data:"http://www.mozilla.org/" }
|
||||||
|
]];
|
||||||
|
|
||||||
|
|
||||||
|
function dumpTransfer(dataTransfer,expect) {
|
||||||
|
dtData = dataTransfer.mozItemCount + "items:\n";
|
||||||
|
for (var i = 0; i < dataTransfer.mozItemCount; i++) {
|
||||||
|
var dtTypes = dataTransfer.mozTypesAt(i);
|
||||||
|
for (var j = 0; j < dtTypes.length; j++) {
|
||||||
|
var actualData = dataTransfer.mozGetDataAt(dtTypes[j],i)
|
||||||
|
if (expect && expect[i] && expect[i][j]) {
|
||||||
|
if (expect[i][j].eqTest)
|
||||||
|
dtData += expect[i][j].eqTest(actualData,expect[i][j].data) ? "ok" : "fail";
|
||||||
|
else
|
||||||
|
dtData += (actualData == expect[i][j].data) ? "ok" : "fail";
|
||||||
|
}
|
||||||
|
dtData += "["+i+"]" + "["+j+"]: " + '"' + dtTypes[j] + '" "' + actualData + '"\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alert(dtData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||||
|
|
||||||
|
var result = synthesizeDragStart($('link1'), dragLinkText, window);
|
||||||
|
is(result, null, "Drag -moz-user-select:none link (#link1)");
|
||||||
|
// if (result) dumpTransfer(result,dragLinkText);
|
||||||
|
|
||||||
|
dragLinkText[0][2].data = "link2";
|
||||||
|
dragLinkText[0][6].data = '<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>'
|
||||||
|
var result = synthesizeDragStart($('link2'), dragLinkText, window);
|
||||||
|
is(result, null, "Drag link (#link2)");
|
||||||
|
// if (result) dumpTransfer(result,dragLinkText);
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SimpleTest.waitForFocus(runTest);
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -262,7 +262,7 @@ try {
|
|||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
didThrow = true;
|
didThrow = true;
|
||||||
}
|
}
|
||||||
// Once this test passes, we shoud test that onerror gets called and
|
// Once this test passes, we should test that onerror gets called and
|
||||||
// that the FileReader object is in the right state during that call.
|
// that the FileReader object is in the right state during that call.
|
||||||
todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
|
todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
|
||||||
|
|
||||||
|
@ -63,7 +63,21 @@ function shouldNotOpen(e)
|
|||||||
function shouldNotReceiveCloseEvent(e)
|
function shouldNotReceiveCloseEvent(e)
|
||||||
{
|
{
|
||||||
var ws = e.target;
|
var ws = e.target;
|
||||||
ok(false, "onclose shouldn't be called on test " + ws._testNumber + "!");
|
var extendedErrorInfo = "";
|
||||||
|
if (!ws._testNumber) {
|
||||||
|
extendedErrorInfo += "\nws members:\n";
|
||||||
|
for (var i in ws) {
|
||||||
|
extendedErrorInfo += (i + ": " + ws[i] + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extendedErrorInfo += "\ne members:\n";
|
||||||
|
for (var i in e) {
|
||||||
|
extendedErrorInfo += (i + ": " + e[i] + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: see bug 578276. This should be a test failure, but it's too flaky on the tbox.
|
||||||
|
ok(true, "onclose shouldn't be called on test " + ws._testNumber + "!" + extendedErrorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldCloseCleanly(e)
|
function shouldCloseCleanly(e)
|
||||||
@ -89,12 +103,15 @@ function CreateTestWS(ws_location, ws_protocol)
|
|||||||
ws = new WebSocket(ws_location, ws_protocol);
|
ws = new WebSocket(ws_location, ws_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ws._testNumber = current_test;
|
||||||
|
ws._receivedCloseEvent = false;
|
||||||
|
ok(true, "added testNumber: " + ws._testNumber +"\n");
|
||||||
|
|
||||||
ws.onerror = function(e)
|
ws.onerror = function(e)
|
||||||
{
|
{
|
||||||
ok(false, "onerror called on test " + e.target._testNumber + "!");
|
ok(false, "onerror called on test " + e.target._testNumber + "!");
|
||||||
};
|
};
|
||||||
ws._testNumber = current_test;
|
|
||||||
ws._receivedCloseEvent = false;
|
|
||||||
ws.addEventListener("close", function(e)
|
ws.addEventListener("close", function(e)
|
||||||
{
|
{
|
||||||
ws._receivedCloseEvent = true;
|
ws._receivedCloseEvent = true;
|
||||||
@ -419,6 +436,7 @@ var status_test17 = "not started";
|
|||||||
window._test17 = function()
|
window._test17 = function()
|
||||||
{
|
{
|
||||||
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 17");
|
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 17");
|
||||||
|
local_ws._testNumber = "local17";
|
||||||
current_test++;
|
current_test++;
|
||||||
|
|
||||||
status_test17 = "started";
|
status_test17 = "started";
|
||||||
@ -491,6 +509,7 @@ function test19()
|
|||||||
window._test20 = function()
|
window._test20 = function()
|
||||||
{
|
{
|
||||||
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 20");
|
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 20");
|
||||||
|
local_ws._testNumber = "local20";
|
||||||
current_test++;
|
current_test++;
|
||||||
|
|
||||||
local_ws.onerror = function()
|
local_ws.onerror = function()
|
||||||
|
@ -138,8 +138,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
|||||||
// If incrementing the generation would cause overflow,
|
// If incrementing the generation would cause overflow,
|
||||||
// don't allow it. Allowing this would allow us to use
|
// don't allow it. Allowing this would allow us to use
|
||||||
// resource handles created from older context generations.
|
// resource handles created from older context generations.
|
||||||
if (mGeneration + 1 == 0)
|
if (!(mGeneration+1).valid())
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
|
||||||
|
|
||||||
if (mWidth == width && mHeight == height)
|
if (mWidth == width && mHeight == height)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -181,7 +181,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
|||||||
mHeight = height;
|
mHeight = height;
|
||||||
|
|
||||||
// increment the generation number
|
// increment the generation number
|
||||||
mGeneration++;
|
++mGeneration;
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@
|
|||||||
#include "GLContext.h"
|
#include "GLContext.h"
|
||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
|
|
||||||
|
#include "CheckedInt.h"
|
||||||
|
|
||||||
#define UNPACK_FLIP_Y_WEBGL 0x9240
|
#define UNPACK_FLIP_Y_WEBGL 0x9240
|
||||||
#define UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
|
#define UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
|
||||||
#define CONTEXT_LOST_WEBGL 0x9242
|
#define CONTEXT_LOST_WEBGL 0x9242
|
||||||
@ -307,7 +309,7 @@ public:
|
|||||||
|
|
||||||
// a number that increments every time we have an event that causes
|
// a number that increments every time we have an event that causes
|
||||||
// all context resources to be lost.
|
// all context resources to be lost.
|
||||||
PRUint32 Generation() { return mGeneration; }
|
PRUint32 Generation() { return mGeneration.value(); }
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
|
nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
|
||||||
nsHTMLCanvasElement *HTMLCanvasElement() {
|
nsHTMLCanvasElement *HTMLCanvasElement() {
|
||||||
@ -317,7 +319,7 @@ protected:
|
|||||||
nsRefPtr<gl::GLContext> gl;
|
nsRefPtr<gl::GLContext> gl;
|
||||||
|
|
||||||
PRInt32 mWidth, mHeight;
|
PRInt32 mWidth, mHeight;
|
||||||
PRUint32 mGeneration;
|
CheckedUint32 mGeneration;
|
||||||
|
|
||||||
PRBool mInvalidated;
|
PRBool mInvalidated;
|
||||||
|
|
||||||
@ -335,6 +337,7 @@ protected:
|
|||||||
PRBool ValidateComparisonEnum(WebGLenum target, const char *info);
|
PRBool ValidateComparisonEnum(WebGLenum target, const char *info);
|
||||||
PRBool ValidateStencilOpEnum(WebGLenum action, const char *info);
|
PRBool ValidateStencilOpEnum(WebGLenum action, const char *info);
|
||||||
PRBool ValidateFaceEnum(WebGLenum target, const char *info);
|
PRBool ValidateFaceEnum(WebGLenum target, const char *info);
|
||||||
|
PRBool ValidateBufferUsageEnum(WebGLenum target, const char *info);
|
||||||
PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
|
PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
|
||||||
PRUint32 *texelSize, const char *info);
|
PRUint32 *texelSize, const char *info);
|
||||||
|
|
||||||
@ -705,7 +708,7 @@ public:
|
|||||||
WebGLuint GLName() { return mName; }
|
WebGLuint GLName() { return mName; }
|
||||||
const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; }
|
const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; }
|
||||||
PRBool LinkStatus() { return mLinkStatus; }
|
PRBool LinkStatus() { return mLinkStatus; }
|
||||||
GLuint Generation() const { return mGeneration; }
|
PRUint32 Generation() const { return mGeneration.value(); }
|
||||||
void SetLinkStatus(PRBool val) { mLinkStatus = val; }
|
void SetLinkStatus(PRBool val) { mLinkStatus = val; }
|
||||||
|
|
||||||
PRBool ContainsShader(WebGLShader *shader) {
|
PRBool ContainsShader(WebGLShader *shader) {
|
||||||
@ -742,10 +745,9 @@ public:
|
|||||||
|
|
||||||
PRBool NextGeneration()
|
PRBool NextGeneration()
|
||||||
{
|
{
|
||||||
GLuint nextGeneration = mGeneration + 1;
|
if (!(mGeneration+1).valid())
|
||||||
if (nextGeneration == 0)
|
|
||||||
return PR_FALSE; // must exit without changing mGeneration
|
return PR_FALSE; // must exit without changing mGeneration
|
||||||
mGeneration = nextGeneration;
|
++mGeneration;
|
||||||
mMapUniformLocations.Clear();
|
mMapUniformLocations.Clear();
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
@ -770,7 +772,7 @@ protected:
|
|||||||
PRPackedBool mLinkStatus;
|
PRPackedBool mLinkStatus;
|
||||||
nsTArray<WebGLShader*> mAttachedShaders;
|
nsTArray<WebGLShader*> mAttachedShaders;
|
||||||
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
|
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
|
||||||
GLuint mGeneration;
|
CheckedUint32 mGeneration;
|
||||||
GLint mUniformMaxNameLength;
|
GLint mUniformMaxNameLength;
|
||||||
GLint mAttribMaxNameLength;
|
GLint mAttribMaxNameLength;
|
||||||
GLint mUniformCount;
|
GLint mUniformCount;
|
||||||
@ -864,7 +866,7 @@ public:
|
|||||||
|
|
||||||
WebGLProgram *Program() const { return mProgram; }
|
WebGLProgram *Program() const { return mProgram; }
|
||||||
GLint Location() const { return mLocation; }
|
GLint Location() const { return mLocation; }
|
||||||
GLuint ProgramGeneration() const { return mProgramGeneration; }
|
PRUint32 ProgramGeneration() const { return mProgramGeneration; }
|
||||||
|
|
||||||
// needed for our generic helpers to check nsIxxx parameters, see GetConcreteObject.
|
// needed for our generic helpers to check nsIxxx parameters, see GetConcreteObject.
|
||||||
PRBool Deleted() { return PR_FALSE; }
|
PRBool Deleted() { return PR_FALSE; }
|
||||||
@ -873,7 +875,7 @@ public:
|
|||||||
NS_DECL_NSIWEBGLUNIFORMLOCATION
|
NS_DECL_NSIWEBGLUNIFORMLOCATION
|
||||||
protected:
|
protected:
|
||||||
WebGLObjectRefPtr<WebGLProgram> mProgram;
|
WebGLObjectRefPtr<WebGLProgram> mProgram;
|
||||||
GLuint mProgramGeneration;
|
PRUint32 mProgramGeneration;
|
||||||
GLint mLocation;
|
GLint mLocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,21 +125,6 @@ WebGLContext::Present()
|
|||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* long sizeInBytes (in GLenum type); */
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WebGLContext::SizeInBytes(WebGLenum type, PRInt32 *retval)
|
|
||||||
{
|
|
||||||
if (type == LOCAL_GL_FLOAT) *retval = sizeof(float);
|
|
||||||
if (type == LOCAL_GL_SHORT) *retval = sizeof(short);
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_SHORT) *retval = sizeof(unsigned short);
|
|
||||||
if (type == LOCAL_GL_BYTE) *retval = 1;
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_BYTE) *retval = 1;
|
|
||||||
if (type == LOCAL_GL_INT) *retval = sizeof(int);
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_INT) *retval = sizeof(unsigned int);
|
|
||||||
if (type == LOCAL_GL_DOUBLE) *retval = sizeof(double);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void GlActiveTexture (in GLenum texture); */
|
/* void GlActiveTexture (in GLenum texture); */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::ActiveTexture(WebGLenum texture)
|
WebGLContext::ActiveTexture(WebGLenum texture)
|
||||||
@ -292,7 +277,7 @@ WebGLContext::BindTexture(WebGLenum target, nsIWebGLTexture *tobj)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SAME_METHOD_4(BlendColor, BlendColor, float, float, float, float)
|
GL_SAME_METHOD_4(BlendColor, BlendColor, WebGLfloat, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||||
|
|
||||||
NS_IMETHODIMP WebGLContext::BlendEquation(WebGLenum mode)
|
NS_IMETHODIMP WebGLContext::BlendEquation(WebGLenum mode)
|
||||||
{
|
{
|
||||||
@ -362,6 +347,12 @@ WebGLContext::BufferData_size(WebGLenum target, WebGLsizei size, WebGLenum usage
|
|||||||
return ErrorInvalidEnum("BufferData: invalid target");
|
return ErrorInvalidEnum("BufferData: invalid target");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
return ErrorInvalidValue("bufferData: negative size");
|
||||||
|
|
||||||
|
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
if (!boundBuffer)
|
if (!boundBuffer)
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
@ -388,6 +379,9 @@ WebGLContext::BufferData_buf(WebGLenum target, js::ArrayBuffer *wb, WebGLenum us
|
|||||||
return ErrorInvalidEnum("BufferData: invalid target");
|
return ErrorInvalidEnum("BufferData: invalid target");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
if (!boundBuffer)
|
if (!boundBuffer)
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
@ -414,6 +408,9 @@ WebGLContext::BufferData_array(WebGLenum target, js::TypedArray *wa, WebGLenum u
|
|||||||
return ErrorInvalidEnum("BufferData: invalid target");
|
return ErrorInvalidEnum("BufferData: invalid target");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
if (!boundBuffer)
|
if (!boundBuffer)
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
@ -449,8 +446,11 @@ WebGLContext::BufferSubData_buf(GLenum target, WebGLsizei byteOffset, js::ArrayB
|
|||||||
if (!boundBuffer)
|
if (!boundBuffer)
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
// XXX check for overflow
|
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + wb->byteLength;
|
||||||
if (byteOffset + wb->byteLength > boundBuffer->ByteLength())
|
if (!checked_neededByteLength.valid())
|
||||||
|
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||||
|
|
||||||
|
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||||
return ErrorInvalidOperation("BufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
|
return ErrorInvalidOperation("BufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
|
||||||
byteOffset, wb->byteLength, boundBuffer->ByteLength());
|
byteOffset, wb->byteLength, boundBuffer->ByteLength());
|
||||||
|
|
||||||
@ -479,8 +479,11 @@ WebGLContext::BufferSubData_array(WebGLenum target, WebGLsizei byteOffset, js::T
|
|||||||
if (!boundBuffer)
|
if (!boundBuffer)
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
// XXX check for overflow
|
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + wa->byteLength;
|
||||||
if (byteOffset + wa->byteLength > boundBuffer->ByteLength())
|
if (!checked_neededByteLength.valid())
|
||||||
|
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||||
|
|
||||||
|
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||||
return ErrorInvalidOperation("BufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
|
return ErrorInvalidOperation("BufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
|
||||||
byteOffset, wa->byteLength, boundBuffer->ByteLength());
|
byteOffset, wa->byteLength, boundBuffer->ByteLength());
|
||||||
|
|
||||||
@ -512,15 +515,15 @@ WebGLContext::Clear(PRUint32 mask)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SAME_METHOD_4(ClearColor, ClearColor, float, float, float, float)
|
GL_SAME_METHOD_4(ClearColor, ClearColor, WebGLfloat, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||||
|
|
||||||
#ifdef USE_GLES2
|
#ifdef USE_GLES2
|
||||||
GL_SAME_METHOD_1(ClearDepthf, ClearDepth, float)
|
GL_SAME_METHOD_1(ClearDepthf, ClearDepth, WebGLfloat)
|
||||||
#else
|
#else
|
||||||
GL_SAME_METHOD_1(ClearDepth, ClearDepth, float)
|
GL_SAME_METHOD_1(ClearDepth, ClearDepth, WebGLfloat)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GL_SAME_METHOD_1(ClearStencil, ClearStencil, PRInt32)
|
GL_SAME_METHOD_1(ClearStencil, ClearStencil, WebGLint)
|
||||||
|
|
||||||
GL_SAME_METHOD_4(ColorMask, ColorMask, WebGLboolean, WebGLboolean, WebGLboolean, WebGLboolean)
|
GL_SAME_METHOD_4(ColorMask, ColorMask, WebGLboolean, WebGLboolean, WebGLboolean, WebGLboolean)
|
||||||
|
|
||||||
@ -640,7 +643,16 @@ WebGLContext::CreateShader(WebGLenum type, nsIWebGLShader **retval)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SAME_METHOD_1(CullFace, CullFace, WebGLenum)
|
NS_IMETHODIMP
|
||||||
|
WebGLContext::CullFace(WebGLenum face)
|
||||||
|
{
|
||||||
|
if (!ValidateFaceEnum(face, "cullFace"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
MakeContextCurrent();
|
||||||
|
gl->fCullFace(face);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::DeleteBuffer(nsIWebGLBuffer *bobj)
|
WebGLContext::DeleteBuffer(nsIWebGLBuffer *bobj)
|
||||||
@ -816,9 +828,9 @@ WebGLContext::DepthFunc(WebGLenum func)
|
|||||||
GL_SAME_METHOD_1(DepthMask, DepthMask, WebGLboolean)
|
GL_SAME_METHOD_1(DepthMask, DepthMask, WebGLboolean)
|
||||||
|
|
||||||
#ifdef USE_GLES2
|
#ifdef USE_GLES2
|
||||||
GL_SAME_METHOD_2(DepthRangef, DepthRange, float, float)
|
GL_SAME_METHOD_2(DepthRangef, DepthRange, WebGLfloat, WebGLfloat)
|
||||||
#else
|
#else
|
||||||
GL_SAME_METHOD_2(DepthRange, DepthRange, float, float)
|
GL_SAME_METHOD_2(DepthRange, DepthRange, WebGLfloat, WebGLfloat)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -863,10 +875,12 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
|||||||
if (!mCurrentProgram)
|
if (!mCurrentProgram)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
if (first+count < first || first+count < count)
|
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
|
||||||
return ErrorInvalidOperation("DrawArrays: overflow in first+count");
|
|
||||||
|
|
||||||
if (!ValidateBuffers(first+count))
|
if (!checked_firstPlusCount.valid())
|
||||||
|
return ErrorInvalidOperation("drawArrays: overflow in first+count");
|
||||||
|
|
||||||
|
if (!ValidateBuffers(checked_firstPlusCount.value()))
|
||||||
return ErrorInvalidOperation("DrawArrays: bound vertex attribute buffers do not have sufficient data for given first and count");
|
return ErrorInvalidOperation("DrawArrays: bound vertex attribute buffers do not have sufficient data for given first and count");
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
@ -897,20 +911,21 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
|
|||||||
if (count < 0 || byteOffset < 0)
|
if (count < 0 || byteOffset < 0)
|
||||||
return ErrorInvalidValue("DrawElements: negative count or offset");
|
return ErrorInvalidValue("DrawElements: negative count or offset");
|
||||||
|
|
||||||
WebGLuint byteCount;
|
CheckedUint32 checked_byteCount;
|
||||||
if (type == LOCAL_GL_UNSIGNED_SHORT) {
|
|
||||||
byteCount = WebGLuint(count) << 1;
|
|
||||||
if (byteCount >> 1 != WebGLuint(count))
|
|
||||||
return ErrorInvalidValue("DrawElements: overflow in byteCount");
|
|
||||||
|
|
||||||
|
if (type == LOCAL_GL_UNSIGNED_SHORT) {
|
||||||
|
checked_byteCount = 2 * CheckedUint32(count);
|
||||||
if (byteOffset % 2 != 0)
|
if (byteOffset % 2 != 0)
|
||||||
return ErrorInvalidValue("DrawElements: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)");
|
return ErrorInvalidValue("DrawElements: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)");
|
||||||
} else if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
} else if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||||
byteCount = count;
|
checked_byteCount = count;
|
||||||
} else {
|
} else {
|
||||||
return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
|
return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checked_byteCount.valid())
|
||||||
|
return ErrorInvalidValue("DrawElements: overflow in byteCount");
|
||||||
|
|
||||||
// If count is 0, there's nothing to do.
|
// If count is 0, there's nothing to do.
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -923,10 +938,12 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
|
|||||||
if (!mBoundElementArrayBuffer)
|
if (!mBoundElementArrayBuffer)
|
||||||
return ErrorInvalidOperation("DrawElements: must have element array buffer binding");
|
return ErrorInvalidOperation("DrawElements: must have element array buffer binding");
|
||||||
|
|
||||||
if (byteOffset+byteCount < WebGLuint(byteOffset) || byteOffset+byteCount < byteCount)
|
CheckedUint32 checked_neededByteCount = checked_byteCount + byteOffset;
|
||||||
|
|
||||||
|
if (!checked_neededByteCount.valid())
|
||||||
return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
|
return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
|
||||||
|
|
||||||
if (byteOffset + byteCount > mBoundElementArrayBuffer->ByteLength())
|
if (checked_neededByteCount.value() > mBoundElementArrayBuffer->ByteLength())
|
||||||
return ErrorInvalidOperation("DrawElements: bound element array buffer is too small for given count and offset");
|
return ErrorInvalidOperation("DrawElements: bound element array buffer is too small for given count and offset");
|
||||||
|
|
||||||
WebGLuint maxIndex = 0;
|
WebGLuint maxIndex = 0;
|
||||||
@ -936,8 +953,13 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
|
|||||||
maxIndex = mBoundElementArrayBuffer->FindMaximum<GLubyte>(count, byteOffset);
|
maxIndex = mBoundElementArrayBuffer->FindMaximum<GLubyte>(count, byteOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// maxIndex+1 because ValidateBuffers expects the number of elements needed
|
// maxIndex+1 because ValidateBuffers expects the number of elements needed.
|
||||||
if (!ValidateBuffers(maxIndex+1)) {
|
// it is very important here to check tha maxIndex+1 doesn't overflow, otherwise the buffer validation is bypassed !!!
|
||||||
|
// maxIndex is a WebGLuint, ValidateBuffers takes a PRUint32, we validate maxIndex+1 as a PRUint32.
|
||||||
|
CheckedUint32 checked_neededCount = CheckedUint32(maxIndex) + 1;
|
||||||
|
if (!checked_neededCount.valid())
|
||||||
|
return ErrorInvalidOperation("drawElements: overflow in maxIndex+1");
|
||||||
|
if (!ValidateBuffers(checked_neededCount.value())) {
|
||||||
return ErrorInvalidOperation("DrawElements: bound vertex attribute buffers do not have sufficient "
|
return ErrorInvalidOperation("DrawElements: bound vertex attribute buffers do not have sufficient "
|
||||||
"data for given indices from the bound element array");
|
"data for given indices from the bound element array");
|
||||||
}
|
}
|
||||||
@ -1306,14 +1328,7 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
#define LOCAL_GL_MAX_VARYING_VECTORS 0x8dfc // not present in desktop OpenGL
|
#define LOCAL_GL_MAX_VARYING_VECTORS 0x8dfc // not present in desktop OpenGL
|
||||||
// temporarily add those defs here, as they're missing from
|
|
||||||
// gfx/thebes/public/GLDefs.h
|
|
||||||
// and from
|
|
||||||
// gfx/layers/opengl/glDefs.h
|
|
||||||
// and I don't know in which of these 2 files they should go (probably we're going to
|
|
||||||
// kill one of them soon?)
|
|
||||||
#define LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
|
|
||||||
#define LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
|
|
||||||
case LOCAL_GL_MAX_VARYING_VECTORS:
|
case LOCAL_GL_MAX_VARYING_VECTORS:
|
||||||
{
|
{
|
||||||
#ifdef USE_GLES2
|
#ifdef USE_GLES2
|
||||||
@ -2117,7 +2132,7 @@ WebGLContext::IsEnabled(WebGLenum cap, WebGLboolean *retval)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SAME_METHOD_1(LineWidth, LineWidth, float)
|
GL_SAME_METHOD_1(LineWidth, LineWidth, WebGLfloat)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::LinkProgram(nsIWebGLProgram *pobj)
|
WebGLContext::LinkProgram(nsIWebGLProgram *pobj)
|
||||||
@ -2179,7 +2194,7 @@ WebGLContext::PixelStorei(WebGLenum pname, WebGLint param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GL_SAME_METHOD_2(PolygonOffset, PolygonOffset, float, float)
|
GL_SAME_METHOD_2(PolygonOffset, PolygonOffset, WebGLfloat, WebGLfloat)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::ReadPixels(PRInt32 dummy)
|
WebGLContext::ReadPixels(PRInt32 dummy)
|
||||||
@ -2232,16 +2247,19 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
PRUint32 packAlignment;
|
PRUint32 packAlignment;
|
||||||
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*) &packAlignment);
|
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*) &packAlignment);
|
||||||
|
|
||||||
PRUint32 plainRowSize = width*size;
|
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
||||||
|
|
||||||
// alignedRowSize = row size rounded up to next multiple of
|
// alignedRowSize = row size rounded up to next multiple of packAlignment
|
||||||
// packAlignment which is a power of 2
|
CheckedUint32 checked_alignedRowSize
|
||||||
PRUint32 alignedRowSize = (plainRowSize + packAlignment-1) &
|
= ((checked_plainRowSize + packAlignment-1) / packAlignment) * packAlignment;
|
||||||
~PRUint32(packAlignment-1);
|
|
||||||
|
|
||||||
PRUint32 neededByteLength = (height-1)*alignedRowSize + plainRowSize;
|
CheckedUint32 checked_neededByteLength
|
||||||
|
= (height-1) * checked_alignedRowSize + checked_plainRowSize;
|
||||||
|
|
||||||
if(neededByteLength > byteLength)
|
if (!checked_neededByteLength.valid())
|
||||||
|
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
|
if (checked_neededByteLength.value() > byteLength)
|
||||||
return ErrorInvalidOperation("ReadPixels: buffer too small");
|
return ErrorInvalidOperation("ReadPixels: buffer too small");
|
||||||
|
|
||||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
|
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
|
||||||
@ -2277,7 +2295,14 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
GLint subrect_end_y = PR_MIN(y+height, boundHeight);
|
GLint subrect_end_y = PR_MIN(y+height, boundHeight);
|
||||||
GLsizei subrect_height = subrect_end_y - subrect_y;
|
GLsizei subrect_height = subrect_end_y - subrect_y;
|
||||||
|
|
||||||
|
if (subrect_width < 0 || subrect_height < 0 ||
|
||||||
|
subrect_width > width || subrect_height)
|
||||||
|
return ErrorInvalidOperation("ReadPixels: integer overflow computing clipped rect size");
|
||||||
|
|
||||||
|
// now we know that subrect_width is in the [0..width] interval, and same for heights.
|
||||||
|
|
||||||
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
|
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
|
||||||
|
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
|
||||||
PRUint32 subrect_plainRowSize = subrect_width * size;
|
PRUint32 subrect_plainRowSize = subrect_width * size;
|
||||||
PRUint32 subrect_alignedRowSize = (subrect_plainRowSize + packAlignment-1) &
|
PRUint32 subrect_alignedRowSize = (subrect_plainRowSize + packAlignment-1) &
|
||||||
~PRUint32(packAlignment-1);
|
~PRUint32(packAlignment-1);
|
||||||
@ -2286,11 +2311,13 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
// create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer
|
// create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer
|
||||||
GLubyte *subrect_data = new GLubyte[subrect_byteLength];
|
GLubyte *subrect_data = new GLubyte[subrect_byteLength];
|
||||||
gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height, format, type, subrect_data);
|
gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height, format, type, subrect_data);
|
||||||
|
|
||||||
|
// notice that this for loop terminates because we already checked that subrect_height is at most height
|
||||||
for (GLint y_inside_subrect = 0; y_inside_subrect < subrect_height; ++y_inside_subrect) {
|
for (GLint y_inside_subrect = 0; y_inside_subrect < subrect_height; ++y_inside_subrect) {
|
||||||
GLint subrect_x_in_dest_buffer = subrect_x - x;
|
GLint subrect_x_in_dest_buffer = subrect_x - x;
|
||||||
GLint subrect_y_in_dest_buffer = subrect_y - y;
|
GLint subrect_y_in_dest_buffer = subrect_y - y;
|
||||||
memcpy(static_cast<GLubyte*>(data)
|
memcpy(static_cast<GLubyte*>(data)
|
||||||
+ alignedRowSize * (subrect_y_in_dest_buffer + y_inside_subrect)
|
+ checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
|
||||||
+ size * subrect_x_in_dest_buffer, // destination
|
+ size * subrect_x_in_dest_buffer, // destination
|
||||||
subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
|
subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
|
||||||
subrect_plainRowSize); // size
|
subrect_plainRowSize); // size
|
||||||
@ -2353,14 +2380,19 @@ WebGLContext::ReadPixels_byteLength_old_API_deprecated(WebGLsizei width, WebGLsi
|
|||||||
PRUint32 packAlignment;
|
PRUint32 packAlignment;
|
||||||
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*) &packAlignment);
|
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*) &packAlignment);
|
||||||
|
|
||||||
PRUint32 plainRowSize = width*size;
|
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
||||||
|
|
||||||
// alignedRowSize = row size rounded up to next multiple of
|
// alignedRowSize = row size rounded up to next multiple of
|
||||||
// packAlignment which is a power of 2
|
// packAlignment which is a power of 2
|
||||||
PRUint32 alignedRowSize = (plainRowSize + packAlignment-1) &
|
CheckedUint32 checked_alignedRowSize
|
||||||
~PRUint32(packAlignment-1);
|
= ((checked_plainRowSize + packAlignment-1) / packAlignment) * packAlignment;
|
||||||
|
|
||||||
*retval = (height-1)*alignedRowSize + plainRowSize;
|
CheckedUint32 checked_neededByteLength = (height-1)*checked_alignedRowSize + checked_plainRowSize;
|
||||||
|
|
||||||
|
if (!checked_neededByteLength.valid())
|
||||||
|
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
|
*retval = checked_neededByteLength.value();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -2395,7 +2427,7 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SAME_METHOD_2(SampleCoverage, SampleCoverage, float, WebGLboolean)
|
GL_SAME_METHOD_2(SampleCoverage, SampleCoverage, WebGLfloat, WebGLboolean)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
|
WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
|
||||||
@ -2943,9 +2975,6 @@ WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type
|
|||||||
if (size < 1 || size > 4)
|
if (size < 1 || size > 4)
|
||||||
return ErrorInvalidValue("VertexAttribPointer: invalid element size");
|
return ErrorInvalidValue("VertexAttribPointer: invalid element size");
|
||||||
|
|
||||||
if (stride < 0)
|
|
||||||
return ErrorInvalidValue("VertexAttribPointer: stride cannot be negative");
|
|
||||||
|
|
||||||
/* XXX make work with bufferSubData & heterogeneous types
|
/* XXX make work with bufferSubData & heterogeneous types
|
||||||
if (type != mBoundArrayBuffer->GLType())
|
if (type != mBoundArrayBuffer->GLType())
|
||||||
return ErrorInvalidOperation("VertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
|
return ErrorInvalidOperation("VertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
|
||||||
@ -3021,11 +3050,15 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
|||||||
if (!ValidateTexFormatAndType(format, type, &texelSize, "texImage2D"))
|
if (!ValidateTexFormatAndType(format, type, &texelSize, "texImage2D"))
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// XXX overflow!
|
CheckedUint32 checked_bytesNeeded = CheckedUint32(width) * height * texelSize;
|
||||||
uint32 bytesNeeded = width * height * texelSize;
|
|
||||||
|
|
||||||
|
if (!checked_bytesNeeded.valid())
|
||||||
|
return ErrorInvalidOperation("texImage2D: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
|
PRUint32 bytesNeeded = checked_bytesNeeded.value();
|
||||||
|
|
||||||
if (byteLength && byteLength < bytesNeeded)
|
if (byteLength && byteLength < bytesNeeded)
|
||||||
return ErrorInvalidValue("TexImage2D: not enough data for operation (need %d, have %d)",
|
return ErrorInvalidOperation("TexImage2D: not enough data for operation (need %d, have %d)",
|
||||||
bytesNeeded, byteLength);
|
bytesNeeded, byteLength);
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
@ -3154,8 +3187,13 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
|
|||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return NS_OK; // ES 2.0 says it has no effect, we better return right now
|
return NS_OK; // ES 2.0 says it has no effect, we better return right now
|
||||||
|
|
||||||
// XXX overflow!
|
CheckedUint32 checked_bytesNeeded = CheckedUint32(width) * height * texelSize;
|
||||||
uint32 bytesNeeded = width * height * texelSize;
|
|
||||||
|
if (!checked_bytesNeeded.valid())
|
||||||
|
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
|
PRUint32 bytesNeeded = checked_bytesNeeded.value();
|
||||||
|
|
||||||
if (byteLength < bytesNeeded)
|
if (byteLength < bytesNeeded)
|
||||||
return ErrorInvalidValue("TexSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
|
return ErrorInvalidValue("TexSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
|
|
||||||
|
#include "CheckedInt.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -112,12 +114,18 @@ WebGLContext::ValidateBuffers(PRUint32 count)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// compute the number of bytes we actually need
|
// compute the number of bytes we actually need
|
||||||
WebGLuint needed = vd.byteOffset + // the base offset
|
CheckedUint32 checked_needed = CheckedUint32(vd.byteOffset) + // the base offset
|
||||||
vd.actualStride() * (count-1) + // to stride to the start of the last element group
|
CheckedUint32(vd.actualStride()) * (count-1) + // to stride to the start of the last element group
|
||||||
vd.componentSize() * vd.size; // and the number of bytes needed for these components
|
CheckedUint32(vd.componentSize()) * vd.size; // and the number of bytes needed for these components
|
||||||
|
|
||||||
if (vd.buf->ByteLength() < needed) {
|
if (!checked_needed.valid()) {
|
||||||
LogMessage("VBO too small for bound attrib index %d: need at least %d bytes, but have only %d", i, needed, vd.buf->ByteLength());
|
LogMessage("Integer overflow computing the size of bound vertex attrib buffer at index %d", i);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vd.buf->ByteLength() < checked_needed.value()) {
|
||||||
|
LogMessage("VBO too small for bound attrib index %d: need at least %d bytes, but have only %d",
|
||||||
|
i, checked_needed.value(), vd.buf->ByteLength());
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,6 +258,19 @@ PRBool WebGLContext::ValidateFaceEnum(WebGLenum target, const char *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *info)
|
||||||
|
{
|
||||||
|
switch (target) {
|
||||||
|
case LOCAL_GL_STREAM_DRAW:
|
||||||
|
case LOCAL_GL_STATIC_DRAW:
|
||||||
|
case LOCAL_GL_DYNAMIC_DRAW:
|
||||||
|
return PR_TRUE;
|
||||||
|
default:
|
||||||
|
ErrorInvalidEnumInfo(info);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
|
PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
|
||||||
PRUint32 *texelSize, const char *info)
|
PRUint32 *texelSize, const char *info)
|
||||||
{
|
{
|
||||||
|
@ -3111,7 +3111,7 @@ nsCanvasRenderingContext2D::SetLineCap(const nsAString& capstyle)
|
|||||||
cap = gfxContext::LINE_CAP_SQUARE;
|
cap = gfxContext::LINE_CAP_SQUARE;
|
||||||
else
|
else
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_OK;
|
||||||
|
|
||||||
mThebes->SetLineCap(cap);
|
mThebes->SetLineCap(cap);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -3147,7 +3147,7 @@ nsCanvasRenderingContext2D::SetLineJoin(const nsAString& joinstyle)
|
|||||||
j = gfxContext::LINE_JOIN_MITER;
|
j = gfxContext::LINE_JOIN_MITER;
|
||||||
else
|
else
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_OK;
|
||||||
|
|
||||||
mThebes->SetLineJoin(j);
|
mThebes->SetLineJoin(j);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -3532,7 +3532,8 @@ nsCanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op)
|
|||||||
else CANVAS_OP_TO_THEBES_OP("xor", XOR)
|
else CANVAS_OP_TO_THEBES_OP("xor", XOR)
|
||||||
// not part of spec, kept here for compat
|
// not part of spec, kept here for compat
|
||||||
else CANVAS_OP_TO_THEBES_OP("over", OVER)
|
else CANVAS_OP_TO_THEBES_OP("over", OVER)
|
||||||
else return NS_ERROR_NOT_IMPLEMENTED;
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
|
else return NS_OK;
|
||||||
|
|
||||||
#undef CANVAS_OP_TO_THEBES_OP
|
#undef CANVAS_OP_TO_THEBES_OP
|
||||||
|
|
||||||
|
@ -1463,7 +1463,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1569,7 +1569,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1596,7 +1596,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1642,7 +1642,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -9131,7 +9131,7 @@ ok(ctx.lineCap === 'butt', "ctx.lineCap === 'butt'");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -9505,7 +9505,7 @@ ok(ctx.lineJoin === 'bevel', "ctx.lineJoin === 'bevel'");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19316,7 +19316,7 @@ ok(canvas.getContext('2D') === null, "canvas.getContext('2D') === null");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19342,7 +19342,7 @@ ok(canvas.getContext("") === null, "canvas.getContext(\"\") === null");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19368,7 +19368,7 @@ ok(canvas.getContext('This is not an implemented context in any real browser') =
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19394,7 +19394,7 @@ ok(canvas.getContext("2d#") === null, "canvas.getContext(\"2d#\") === null");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19420,7 +19420,7 @@ ok(canvas.getContext("2d\0") === null, "canvas.getContext(\"2d\\0\") === null");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -19446,7 +19446,7 @@ ok(canvas.getContext("2\uFF44") === null, "canvas.getContext(\"2\\uFF44\") === n
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -20607,7 +20607,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -20715,7 +20715,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -140,11 +140,11 @@ function go() {
|
|||||||
checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
|
checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
|
||||||
checkGetAttachedShaders([fs, vs, fs2, vs2], [], [fs, vs, fs2, vs2],
|
checkGetAttachedShaders([fs, vs, fs2, vs2], [], [fs, vs, fs2, vs2],
|
||||||
"attaching some shaders should give the expected list");
|
"attaching some shaders should give the expected list");
|
||||||
checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it shoud leave an empty list");
|
checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it should leave an empty list");
|
||||||
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs, fs2, vs2], [],
|
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs, fs2, vs2], [],
|
||||||
"attaching some shaders and detaching them in same order shoud leave an empty list");
|
"attaching some shaders and detaching them in same order should leave an empty list");
|
||||||
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2, vs, fs2], [],
|
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2, vs, fs2], [],
|
||||||
"attaching some shaders and detaching them in random order shoud leave an empty list");
|
"attaching some shaders and detaching them in random order should leave an empty list");
|
||||||
checkGetAttachedShaders([fs, vs, fs2, vs2], [vs], [fs, fs2, vs2],
|
checkGetAttachedShaders([fs, vs, fs2, vs2], [vs], [fs, fs2, vs2],
|
||||||
"attaching and detaching some shaders should leave the difference list");
|
"attaching and detaching some shaders should leave the difference list");
|
||||||
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2], [vs, fs2],
|
checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2], [vs, fs2],
|
||||||
|
@ -139,10 +139,13 @@ nsEventListenerInfo::ToSource(nsAString& aResult)
|
|||||||
JSContext* cx = nsnull;
|
JSContext* cx = nsnull;
|
||||||
stack->GetSafeJSContext(&cx);
|
stack->GetSafeJSContext(&cx);
|
||||||
if (cx && NS_SUCCEEDED(stack->Push(cx))) {
|
if (cx && NS_SUCCEEDED(stack->Push(cx))) {
|
||||||
JSAutoRequest ar(cx);
|
{
|
||||||
JSString* str = JS_ValueToSource(cx, v);
|
// Extra block to finish the auto request before calling pop
|
||||||
if (str) {
|
JSAutoRequest ar(cx);
|
||||||
aResult.Assign(nsDependentJSString(str));
|
JSString* str = JS_ValueToSource(cx, v);
|
||||||
|
if (str) {
|
||||||
|
aResult.Assign(nsDependentJSString(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack->Pop(&cx);
|
stack->Pop(&cx);
|
||||||
}
|
}
|
||||||
|
@ -1581,9 +1581,9 @@ nsGenericHTMLElement::ParseTableVAlignValue(const nsAString& aString,
|
|||||||
return aResult.ParseEnumValue(aString, kTableVAlignTable, PR_FALSE);
|
return aResult.ParseEnumValue(aString, kTableVAlignTable, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsGenericHTMLElement::ParseDivAlignValue(const nsAString& aString,
|
nsGenericHTMLElement::ParseDivAlignValue(const nsAString& aString,
|
||||||
nsAttrValue& aResult) const
|
nsAttrValue& aResult)
|
||||||
{
|
{
|
||||||
return aResult.ParseEnumValue(aString, kDivAlignTable, PR_FALSE);
|
return aResult.ParseEnumValue(aString, kDivAlignTable, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
@ -253,8 +253,8 @@ public:
|
|||||||
* @param aResult the resulting HTMLValue
|
* @param aResult the resulting HTMLValue
|
||||||
* @return whether the value was parsed
|
* @return whether the value was parsed
|
||||||
*/
|
*/
|
||||||
PRBool ParseDivAlignValue(const nsAString& aString,
|
static PRBool ParseDivAlignValue(const nsAString& aString,
|
||||||
nsAttrValue& aResult) const;
|
nsAttrValue& aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a table halign string to value (left/right/center/char/justify)
|
* Convert a table halign string to value (left/right/center/char/justify)
|
||||||
|
@ -202,13 +202,7 @@ nsHTMLCanvasElement::ToDataURL(const nsAString& aType, const nsAString& aParams,
|
|||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString type(aType);
|
return ToDataURLImpl(aType, aParams, aDataURL);
|
||||||
|
|
||||||
if (type.IsEmpty()) {
|
|
||||||
type.AssignLiteral("image/png");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ToDataURLImpl(type, aParams, aDataURL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -229,13 +223,13 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
|||||||
const nsAString& aEncoderOptions,
|
const nsAString& aEncoderOptions,
|
||||||
nsAString& aDataURL)
|
nsAString& aDataURL)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
bool fallbackToPNG = false;
|
||||||
|
|
||||||
// We get an input stream from the context. If more than one context type
|
// We get an input stream from the context. If more than one context type
|
||||||
// is supported in the future, this will have to be changed to do the right
|
// is supported in the future, this will have to be changed to do the right
|
||||||
// thing. For now, just assume that the 2D context has all the goods.
|
// thing. For now, just assume that the 2D context has all the goods.
|
||||||
nsCOMPtr<nsICanvasRenderingContextInternal> context;
|
nsCOMPtr<nsICanvasRenderingContextInternal> context;
|
||||||
rv = GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(context));
|
nsresult rv = GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(context));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// get image bytes
|
// get image bytes
|
||||||
@ -244,8 +238,15 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
|||||||
rv = context->GetInputStream(nsPromiseFlatCString(aMimeType8).get(),
|
rv = context->GetInputStream(nsPromiseFlatCString(aMimeType8).get(),
|
||||||
nsPromiseFlatString(aEncoderOptions).get(),
|
nsPromiseFlatString(aEncoderOptions).get(),
|
||||||
getter_AddRefs(imgStream));
|
getter_AddRefs(imgStream));
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
if (NS_FAILED(rv)) {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
// Use image/png instead.
|
||||||
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
|
fallbackToPNG = true;
|
||||||
|
rv = context->GetInputStream("image/png",
|
||||||
|
nsPromiseFlatString(aEncoderOptions).get(),
|
||||||
|
getter_AddRefs(imgStream));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
// Generally, there will be only one chunk of data, and it will be available
|
// Generally, there will be only one chunk of data, and it will be available
|
||||||
// for us to read right away, so optimize this case.
|
// for us to read right away, so optimize this case.
|
||||||
@ -283,8 +284,12 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
|||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
// build data URL string
|
// build data URL string
|
||||||
aDataURL = NS_LITERAL_STRING("data:") + aMimeType +
|
if (fallbackToPNG)
|
||||||
NS_LITERAL_STRING(";base64,") + NS_ConvertUTF8toUTF16(encodedImg);
|
aDataURL = NS_LITERAL_STRING("data:image/png;base64,") +
|
||||||
|
NS_ConvertUTF8toUTF16(encodedImg);
|
||||||
|
else
|
||||||
|
aDataURL = NS_LITERAL_STRING("data:") + aMimeType +
|
||||||
|
NS_LITERAL_STRING(";base64,") + NS_ConvertUTF8toUTF16(encodedImg);
|
||||||
|
|
||||||
PR_Free(encodedImg);
|
PR_Free(encodedImg);
|
||||||
|
|
||||||
@ -309,7 +314,7 @@ nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
|||||||
(ctxId[i] != '_'))
|
(ctxId[i] != '_'))
|
||||||
{
|
{
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +331,7 @@ nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
*aContext = nsnull;
|
*aContext = nsnull;
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = ctx->SetCanvasElement(this);
|
rv = ctx->SetCanvasElement(this);
|
||||||
@ -376,7 +381,7 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
|
|||||||
mCurrentContextId.Assign(aContextId);
|
mCurrentContextId.Assign(aContextId);
|
||||||
} else if (!mCurrentContextId.Equals(aContextId)) {
|
} else if (!mCurrentContextId.Equals(aContextId)) {
|
||||||
//XXX eventually allow for more than one active context on a given canvas
|
//XXX eventually allow for more than one active context on a given canvas
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ADDREF (*aContext = mCurrentContext);
|
NS_ADDREF (*aContext = mCurrentContext);
|
||||||
|
@ -116,7 +116,7 @@ function checkHtmlForIDLAttribute(element)
|
|||||||
|
|
||||||
// DOMSettableTokenList is tested in another bug so we just test assignation
|
// DOMSettableTokenList is tested in another bug so we just test assignation
|
||||||
element.htmlFor.value = 'a b c';
|
element.htmlFor.value = 'a b c';
|
||||||
is(element.htmlFor, 'a b c', "htmlFor shoud have changed");
|
is(element.htmlFor, 'a b c', "htmlFor should have changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitForm()
|
function submitForm()
|
||||||
|
@ -148,11 +148,13 @@ NS_NewHTMLNOTUSEDElement(nsINodeInfo *aNodeInfo, PRUint32 aFromParser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define HTML_TAG(_tag, _classname) NS_NewHTML##_classname##Element,
|
#define HTML_TAG(_tag, _classname) NS_NewHTML##_classname##Element,
|
||||||
|
#define HTML_HTMLELEMENT_TAG(_tag) NS_NewHTMLElement,
|
||||||
#define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement,
|
#define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement,
|
||||||
static const contentCreatorCallback sContentCreatorCallbacks[] = {
|
static const contentCreatorCallback sContentCreatorCallbacks[] = {
|
||||||
NS_NewHTMLUnknownElement,
|
NS_NewHTMLUnknownElement,
|
||||||
#include "nsHTMLTagList.h"
|
#include "nsHTMLTagList.h"
|
||||||
#undef HTML_TAG
|
#undef HTML_TAG
|
||||||
|
#undef HTML_HTMLELEMENT_TAG
|
||||||
#undef HTML_OTHER
|
#undef HTML_OTHER
|
||||||
NS_NewHTMLUnknownElement
|
NS_NewHTMLUnknownElement
|
||||||
};
|
};
|
||||||
|
@ -1254,21 +1254,11 @@ nsHTMLDocument::CreateElement(const nsAString& aTagName,
|
|||||||
nsIDOMElement** aReturn)
|
nsIDOMElement** aReturn)
|
||||||
{
|
{
|
||||||
*aReturn = nsnull;
|
*aReturn = nsnull;
|
||||||
nsresult rv;
|
nsresult rv = nsContentUtils::CheckQName(aTagName, PR_FALSE);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
nsAutoString tagName(aTagName);
|
nsAutoString tagName(aTagName);
|
||||||
|
|
||||||
// if we are in quirks, allow surrounding '<' '>' for IE compat
|
|
||||||
if (mCompatMode == eCompatibility_NavQuirks &&
|
|
||||||
tagName.Length() > 2 &&
|
|
||||||
tagName.First() == '<' &&
|
|
||||||
tagName.Last() == '>') {
|
|
||||||
tagName = Substring(tagName, 1, tagName.Length() - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nsContentUtils::CheckQName(tagName, PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (IsHTML()) {
|
if (IsHTML()) {
|
||||||
ToLowerCase(tagName);
|
ToLowerCase(tagName);
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1006,10 @@ nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
|
|||||||
nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
|
nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
|
||||||
|
|
||||||
// check the attributes we allow that contain URIs
|
// check the attributes we allow that contain URIs
|
||||||
if (IsAttrURI(keyAtom)) {
|
// special case src attributes for img tags, because they can't
|
||||||
|
// run any dangerous code.
|
||||||
|
if (IsAttrURI(keyAtom) &&
|
||||||
|
!(nodeType == eHTMLTag_img && keyAtom == nsGkAtoms::src)) {
|
||||||
if (!baseURI) {
|
if (!baseURI) {
|
||||||
baseURI = aContent->GetBaseURI();
|
baseURI = aContent->GetBaseURI();
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ _TEST_FILES = test_bug1682.html \
|
|||||||
test_bug311681.xhtml \
|
test_bug311681.xhtml \
|
||||||
test_bug324378.html \
|
test_bug324378.html \
|
||||||
test_bug332848.xhtml \
|
test_bug332848.xhtml \
|
||||||
|
test_bug340017.xhtml \
|
||||||
test_bug359657.html \
|
test_bug359657.html \
|
||||||
test_bug369370.html \
|
test_bug369370.html \
|
||||||
bug369370-popup.png \
|
bug369370-popup.png \
|
||||||
@ -95,13 +96,13 @@ _TEST_FILES = test_bug1682.html \
|
|||||||
test_bug481647.html \
|
test_bug481647.html \
|
||||||
test_bug482659.html \
|
test_bug482659.html \
|
||||||
test_bug486741.html \
|
test_bug486741.html \
|
||||||
|
test_bug489532.html \
|
||||||
test_bug497242.xhtml \
|
test_bug497242.xhtml \
|
||||||
test_bug512367.html \
|
|
||||||
test_bug570375.html \
|
|
||||||
test_bug340017.xhtml \
|
|
||||||
test_bug499092.html \
|
test_bug499092.html \
|
||||||
bug499092.xml \
|
bug499092.xml \
|
||||||
bug499092.html \
|
bug499092.html \
|
||||||
|
test_bug512367.html \
|
||||||
|
test_bug570376.html \
|
||||||
test_bug571981.html \
|
test_bug571981.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
32
content/html/document/test/test_bug489532.html
Normal file
32
content/html/document/test/test_bug489532.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=489532
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 489532</title>
|
||||||
|
<script src="/MochiKit/packed.js"></script>
|
||||||
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=489532">Mozilla Bug 489532</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script>
|
||||||
|
/** Test for Bug 489532 **/
|
||||||
|
try {
|
||||||
|
document.createElement("<div>");
|
||||||
|
ok(false, "Should throw.")
|
||||||
|
} catch (e) {
|
||||||
|
ok(e instanceof DOMException, "Expected DOMException.");
|
||||||
|
is(e.code, DOMException.INVALID_CHARACTER_ERR,
|
||||||
|
"Expected INVALID_CHARACTER_ERR.");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,16 +1,16 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
<!--
|
<!--
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=570375
|
https://bugzilla.mozilla.org/show_bug.cgi?id=570376
|
||||||
-->
|
-->
|
||||||
<head>
|
<head>
|
||||||
<title>Test for Bug 570375</title>
|
<title>Test for Bug 570376</title>
|
||||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570375">Mozilla Bug 570375</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570376">Mozilla Bug 570376</a>
|
||||||
<p id="display">
|
<p id="display">
|
||||||
<iframe id="testiframe"></iframe>
|
<iframe id="testiframe"></iframe>
|
||||||
</p>
|
</p>
|
||||||
@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=570375
|
|||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
|
||||||
/** Test for Bug 570375
|
/** Test for Bug 570376
|
||||||
Don't crash loading <form><legend> with the html5 parser preffed off.
|
Don't crash loading <form><legend> with the html5 parser preffed off.
|
||||||
**/
|
**/
|
||||||
|
|
@ -126,9 +126,9 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
|
|||||||
PRUint32 picXLimit;
|
PRUint32 picXLimit;
|
||||||
PRUint32 picYLimit;
|
PRUint32 picYLimit;
|
||||||
if (!AddOverflow32(aInfo.mPicture.x, aInfo.mPicture.width, picXLimit) ||
|
if (!AddOverflow32(aInfo.mPicture.x, aInfo.mPicture.width, picXLimit) ||
|
||||||
picXLimit > PRUint32(aBuffer.mPlanes[0].mStride) ||
|
picXLimit > aBuffer.mPlanes[0].mStride ||
|
||||||
!AddOverflow32(aInfo.mPicture.y, aInfo.mPicture.height, picYLimit) ||
|
!AddOverflow32(aInfo.mPicture.y, aInfo.mPicture.height, picYLimit) ||
|
||||||
picYLimit > PRUint32(aBuffer.mPlanes[0].mHeight))
|
picYLimit > aBuffer.mPlanes[0].mHeight)
|
||||||
{
|
{
|
||||||
// The specified picture dimensions can't be contained inside the video
|
// The specified picture dimensions can't be contained inside the video
|
||||||
// frame, we'll stomp memory if we try to copy it. Fail.
|
// frame, we'll stomp memory if we try to copy it. Fail.
|
||||||
|
@ -904,10 +904,11 @@ PRInt64 nsOggReader::FindEndTime(PRInt64 aEndOffset)
|
|||||||
// This page is from a bitstream which we haven't encountered yet.
|
// This page is from a bitstream which we haven't encountered yet.
|
||||||
// It's probably from a new "link" in a "chained" ogg. Don't
|
// It's probably from a new "link" in a "chained" ogg. Don't
|
||||||
// bother even trying to find a duration...
|
// bother even trying to find a duration...
|
||||||
|
endTime = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt64 t = codecState ? codecState->Time(granulepos) : -1;
|
PRInt64 t = codecState->Time(granulepos);
|
||||||
if (t != -1) {
|
if (t != -1) {
|
||||||
endTime = t;
|
endTime = t;
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,9 @@ nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers)
|
|||||||
mResampleNeeded = PR_FALSE;
|
mResampleNeeded = PR_FALSE;
|
||||||
|
|
||||||
// STEP 1: Bring model up to date
|
// STEP 1: Bring model up to date
|
||||||
|
// (i) Rewind elements where necessary
|
||||||
|
// (ii) Run milestone samples
|
||||||
|
RewindElements();
|
||||||
DoMilestoneSamples();
|
DoMilestoneSamples();
|
||||||
|
|
||||||
// STEP 2: Sample the child time containers
|
// STEP 2: Sample the child time containers
|
||||||
@ -402,6 +405,56 @@ nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers)
|
|||||||
NS_ASSERTION(!mResampleNeeded, "Resample dirty flag set during sample!");
|
NS_ASSERTION(!mResampleNeeded, "Resample dirty flag set during sample!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILAnimationController::RewindElements()
|
||||||
|
{
|
||||||
|
PRBool rewindNeeded = PR_FALSE;
|
||||||
|
mChildContainerTable.EnumerateEntries(RewindNeeded, &rewindNeeded);
|
||||||
|
if (!rewindNeeded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mAnimationElementTable.EnumerateEntries(RewindAnimation, nsnull);
|
||||||
|
mChildContainerTable.EnumerateEntries(ClearRewindNeeded, nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ PR_CALLBACK PLDHashOperator
|
||||||
|
nsSMILAnimationController::RewindNeeded(TimeContainerPtrKey* aKey,
|
||||||
|
void* aData)
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(aData,
|
||||||
|
"Null data pointer during time container enumeration");
|
||||||
|
PRBool* rewindNeeded = static_cast<PRBool*>(aData);
|
||||||
|
|
||||||
|
nsSMILTimeContainer* container = aKey->GetKey();
|
||||||
|
if (container->NeedsRewind()) {
|
||||||
|
*rewindNeeded = PR_TRUE;
|
||||||
|
return PL_DHASH_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ PR_CALLBACK PLDHashOperator
|
||||||
|
nsSMILAnimationController::RewindAnimation(AnimationElementPtrKey* aKey,
|
||||||
|
void* aData)
|
||||||
|
{
|
||||||
|
nsISMILAnimationElement* animElem = aKey->GetKey();
|
||||||
|
nsSMILTimeContainer* timeContainer = animElem->GetTimeContainer();
|
||||||
|
if (timeContainer && timeContainer->NeedsRewind()) {
|
||||||
|
animElem->TimedElement().Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ PR_CALLBACK PLDHashOperator
|
||||||
|
nsSMILAnimationController::ClearRewindNeeded(TimeContainerPtrKey* aKey,
|
||||||
|
void* aData)
|
||||||
|
{
|
||||||
|
aKey->GetKey()->ClearNeedsRewind();
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsSMILAnimationController::DoMilestoneSamples()
|
nsSMILAnimationController::DoMilestoneSamples()
|
||||||
{
|
{
|
||||||
@ -542,6 +595,7 @@ nsSMILAnimationController::SampleTimeContainer(TimeContainerPtrKey* aKey,
|
|||||||
(container->NeedsSample() || !params->mSkipUnchangedContainers)) {
|
(container->NeedsSample() || !params->mSkipUnchangedContainers)) {
|
||||||
container->ClearMilestones();
|
container->ClearMilestones();
|
||||||
container->Sample();
|
container->Sample();
|
||||||
|
container->MarkSeekFinished();
|
||||||
params->mActiveContainers->PutEntry(container);
|
params->mActiveContainers->PutEntry(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,6 +641,8 @@ nsSMILAnimationController::SampleTimedElement(
|
|||||||
|
|
||||||
nsSMILTime containerTime = timeContainer->GetCurrentTime();
|
nsSMILTime containerTime = timeContainer->GetCurrentTime();
|
||||||
|
|
||||||
|
NS_ABORT_IF_FALSE(!timeContainer->IsSeeking(),
|
||||||
|
"Doing a regular sample but the time container is still seeking");
|
||||||
aElement->TimedElement().SampleAt(containerTime);
|
aElement->TimedElement().SampleAt(containerTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +152,21 @@ protected:
|
|||||||
// Sample-related callbacks and implementation helpers
|
// Sample-related callbacks and implementation helpers
|
||||||
virtual void DoSample();
|
virtual void DoSample();
|
||||||
void DoSample(PRBool aSkipUnchangedContainers);
|
void DoSample(PRBool aSkipUnchangedContainers);
|
||||||
|
|
||||||
|
void RewindElements();
|
||||||
|
PR_STATIC_CALLBACK(PLDHashOperator) RewindNeeded(
|
||||||
|
TimeContainerPtrKey* aKey, void* aData);
|
||||||
|
PR_STATIC_CALLBACK(PLDHashOperator) RewindAnimation(
|
||||||
|
AnimationElementPtrKey* aKey, void* aData);
|
||||||
|
PR_STATIC_CALLBACK(PLDHashOperator) ClearRewindNeeded(
|
||||||
|
TimeContainerPtrKey* aKey, void* aData);
|
||||||
|
|
||||||
void DoMilestoneSamples();
|
void DoMilestoneSamples();
|
||||||
PR_STATIC_CALLBACK(PLDHashOperator) GetNextMilestone(
|
PR_STATIC_CALLBACK(PLDHashOperator) GetNextMilestone(
|
||||||
TimeContainerPtrKey* aKey, void* aData);
|
TimeContainerPtrKey* aKey, void* aData);
|
||||||
PR_STATIC_CALLBACK(PLDHashOperator) GetMilestoneElements(
|
PR_STATIC_CALLBACK(PLDHashOperator) GetMilestoneElements(
|
||||||
TimeContainerPtrKey* aKey, void* aData);
|
TimeContainerPtrKey* aKey, void* aData);
|
||||||
|
|
||||||
PR_STATIC_CALLBACK(PLDHashOperator) SampleTimeContainer(
|
PR_STATIC_CALLBACK(PLDHashOperator) SampleTimeContainer(
|
||||||
TimeContainerPtrKey* aKey, void* aData);
|
TimeContainerPtrKey* aKey, void* aData);
|
||||||
PR_STATIC_CALLBACK(PLDHashOperator) SampleAnimation(
|
PR_STATIC_CALLBACK(PLDHashOperator) SampleAnimation(
|
||||||
|
@ -74,9 +74,9 @@ nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime,
|
|||||||
nsSMILInterval* aBaseInterval)
|
nsSMILInterval* aBaseInterval)
|
||||||
: mTime(aTime),
|
: mTime(aTime),
|
||||||
mFlags(0),
|
mFlags(0),
|
||||||
mSerial(0),
|
|
||||||
mVisited(PR_FALSE),
|
mVisited(PR_FALSE),
|
||||||
mChainEnd(PR_FALSE),
|
mFixedEndpointRefCnt(0),
|
||||||
|
mSerial(0),
|
||||||
mCreator(aCreator),
|
mCreator(aCreator),
|
||||||
mBaseInterval(nsnull) // This will get set to aBaseInterval in a call to
|
mBaseInterval(nsnull) // This will get set to aBaseInterval in a call to
|
||||||
// SetBaseInterval() at end of constructor
|
// SetBaseInterval() at end of constructor
|
||||||
@ -87,7 +87,7 @@ nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_DOM:
|
case SOURCE_DOM:
|
||||||
mFlags = kClearOnReset | kFromDOM;
|
mFlags = kDynamic | kFromDOM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_SYNCBASE:
|
case SOURCE_SYNCBASE:
|
||||||
@ -95,7 +95,7 @@ nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_EVENT:
|
case SOURCE_EVENT:
|
||||||
mFlags = kClearOnReset;
|
mFlags = kDynamic;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +106,9 @@ nsSMILInstanceTime::~nsSMILInstanceTime()
|
|||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(!mBaseInterval && !mCreator,
|
NS_ABORT_IF_FALSE(!mBaseInterval && !mCreator,
|
||||||
"Destroying instance time without first calling Unlink()");
|
"Destroying instance time without first calling Unlink()");
|
||||||
|
NS_ABORT_IF_FALSE(mFixedEndpointRefCnt == 0,
|
||||||
|
"Destroying instance time that is still used as the fixed endpoint of an "
|
||||||
|
"interval");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -129,12 +132,9 @@ nsSMILInstanceTime::HandleChangedInterval(
|
|||||||
"Got call to HandleChangedInterval on an independent instance time.");
|
"Got call to HandleChangedInterval on an independent instance time.");
|
||||||
NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not.");
|
NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not.");
|
||||||
|
|
||||||
if (mVisited || mChainEnd) {
|
if (mVisited) {
|
||||||
// We're breaking the cycle here but we need to ensure that if we later
|
// Break the cycle here
|
||||||
// receive a change notice in a different context (e.g. due to a time
|
Unlink();
|
||||||
// container change) that we don't end up following the chain further and so
|
|
||||||
// we set a flag to that effect.
|
|
||||||
mChainEnd = PR_TRUE;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,20 +152,63 @@ void
|
|||||||
nsSMILInstanceTime::HandleDeletedInterval()
|
nsSMILInstanceTime::HandleDeletedInterval()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mBaseInterval,
|
NS_ABORT_IF_FALSE(mBaseInterval,
|
||||||
"Got call to HandleDeletedInterval on an independent instance time.");
|
"Got call to HandleDeletedInterval on an independent instance time");
|
||||||
NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not.");
|
NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not");
|
||||||
|
|
||||||
mBaseInterval = nsnull;
|
mBaseInterval = nsnull;
|
||||||
|
mFlags &= ~kMayUpdate; // Can't update without a base interval
|
||||||
|
|
||||||
nsRefPtr<nsSMILInstanceTime> deathGrip(this);
|
nsRefPtr<nsSMILInstanceTime> deathGrip(this);
|
||||||
mCreator->HandleDeletedInstanceTime(*this);
|
mCreator->HandleDeletedInstanceTime(*this);
|
||||||
mCreator = nsnull;
|
mCreator = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
void
|
||||||
nsSMILInstanceTime::IsDependent(const nsSMILInstanceTime& aOther) const
|
nsSMILInstanceTime::HandleFilteredInterval()
|
||||||
{
|
{
|
||||||
if (mVisited || mChainEnd)
|
NS_ABORT_IF_FALSE(mBaseInterval,
|
||||||
|
"Got call to HandleFilteredInterval on an independent instance time");
|
||||||
|
|
||||||
|
mBaseInterval = nsnull;
|
||||||
|
mFlags &= ~kMayUpdate; // Can't update without a base interval
|
||||||
|
mCreator = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsSMILInstanceTime::ShouldPreserve() const
|
||||||
|
{
|
||||||
|
return mFixedEndpointRefCnt > 0 || (mFlags & kWasDynamicEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILInstanceTime::UnmarkShouldPreserve()
|
||||||
|
{
|
||||||
|
mFlags &= ~kWasDynamicEndpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILInstanceTime::AddRefFixedEndpoint()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mFixedEndpointRefCnt < PR_UINT16_MAX,
|
||||||
|
"Fixed endpoint reference count upper limit reached");
|
||||||
|
++mFixedEndpointRefCnt;
|
||||||
|
mFlags &= ~kMayUpdate; // Once fixed, always fixed
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILInstanceTime::ReleaseFixedEndpoint()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mFixedEndpointRefCnt > 0, "Duplicate release");
|
||||||
|
--mFixedEndpointRefCnt;
|
||||||
|
if (mFixedEndpointRefCnt == 0 && IsDynamic()) {
|
||||||
|
mFlags |= kWasDynamicEndpoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsSMILInstanceTime::IsDependentOn(const nsSMILInstanceTime& aOther) const
|
||||||
|
{
|
||||||
|
if (mVisited)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
const nsSMILInstanceTime* myBaseTime = GetBaseTime();
|
const nsSMILInstanceTime* myBaseTime = GetBaseTime();
|
||||||
@ -177,7 +220,7 @@ nsSMILInstanceTime::IsDependent(const nsSMILInstanceTime& aOther) const
|
|||||||
|
|
||||||
// mVisited is mutable
|
// mVisited is mutable
|
||||||
AutoBoolSetter setVisited(const_cast<nsSMILInstanceTime*>(this)->mVisited);
|
AutoBoolSetter setVisited(const_cast<nsSMILInstanceTime*>(this)->mVisited);
|
||||||
return myBaseTime->IsDependent(aOther);
|
return myBaseTime->IsDependentOn(aOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -92,24 +92,31 @@ public:
|
|||||||
PRBool aBeginObjectChanged,
|
PRBool aBeginObjectChanged,
|
||||||
PRBool aEndObjectChanged);
|
PRBool aEndObjectChanged);
|
||||||
void HandleDeletedInterval();
|
void HandleDeletedInterval();
|
||||||
|
void HandleFilteredInterval();
|
||||||
|
|
||||||
const nsSMILTimeValue& Time() const { return mTime; }
|
const nsSMILTimeValue& Time() const { return mTime; }
|
||||||
const nsSMILTimeValueSpec* GetCreator() const { return mCreator; }
|
const nsSMILTimeValueSpec* GetCreator() const { return mCreator; }
|
||||||
|
|
||||||
PRBool ClearOnReset() const { return !!(mFlags & kClearOnReset); }
|
PRBool IsDynamic() const { return !!(mFlags & kDynamic); }
|
||||||
PRBool MayUpdate() const { return !!(mFlags & kMayUpdate); }
|
PRBool IsFixedTime() const { return !(mFlags & kMayUpdate); }
|
||||||
PRBool FromDOM() const { return !!(mFlags & kFromDOM); }
|
PRBool FromDOM() const { return !!(mFlags & kFromDOM); }
|
||||||
|
|
||||||
void MarkNoLongerUpdating() { mFlags &= ~kMayUpdate; }
|
PRBool ShouldPreserve() const;
|
||||||
|
void UnmarkShouldPreserve();
|
||||||
|
|
||||||
|
void AddRefFixedEndpoint();
|
||||||
|
void ReleaseFixedEndpoint();
|
||||||
|
|
||||||
void DependentUpdate(const nsSMILTimeValue& aNewTime)
|
void DependentUpdate(const nsSMILTimeValue& aNewTime)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(MayUpdate(),
|
NS_ABORT_IF_FALSE(!IsFixedTime(),
|
||||||
"Updating an instance time that is not expected to be updated");
|
"Updating an instance time that is not expected to be updated");
|
||||||
mTime = aNewTime;
|
mTime = aNewTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsDependent(const nsSMILInstanceTime& aOther) const;
|
PRBool IsDependent() const { return !!mBaseInterval; }
|
||||||
|
PRBool IsDependentOn(const nsSMILInstanceTime& aOther) const;
|
||||||
|
const nsSMILInterval* GetBaseInterval() const { return mBaseInterval; }
|
||||||
|
|
||||||
PRBool SameTimeAndBase(const nsSMILInstanceTime& aOther) const
|
PRBool SameTimeAndBase(const nsSMILInstanceTime& aOther) const
|
||||||
{
|
{
|
||||||
@ -131,15 +138,16 @@ protected:
|
|||||||
|
|
||||||
// Internal flags used to represent the behaviour of different instance times
|
// Internal flags used to represent the behaviour of different instance times
|
||||||
enum {
|
enum {
|
||||||
// Indicates if this instance time should be removed when the owning timed
|
// Indicates that this instance time was generated by an event or a DOM
|
||||||
// element is reset. True for events and DOM calls.
|
// call. Such instance times require special handling when (i) the owning
|
||||||
kClearOnReset = 1,
|
// element is reset, and (ii) when a backwards seek is performed and the
|
||||||
|
// timing model is reconstructed.
|
||||||
|
kDynamic = 1,
|
||||||
|
|
||||||
// Indicates that this instance time is referred to by an
|
// Indicates that this instance time is referred to by an
|
||||||
// nsSMILTimeValueSpec and as such may be updated. Such instance time should
|
// nsSMILTimeValueSpec and as such may be updated. Such instance time should
|
||||||
// not be filtered out by the nsSMILTimedElement even if they appear to be
|
// not be filtered out by the nsSMILTimedElement even if they appear to be
|
||||||
// in the past as they may be updated to a future time. Initially set for
|
// in the past as they may be updated to a future time.
|
||||||
// syncbase-generated times until they are frozen.
|
|
||||||
kMayUpdate = 2,
|
kMayUpdate = 2,
|
||||||
|
|
||||||
// Indicates that this instance time was generated from the DOM as opposed
|
// Indicates that this instance time was generated from the DOM as opposed
|
||||||
@ -147,17 +155,33 @@ protected:
|
|||||||
// reset we should clear all the instance times that have been generated by
|
// reset we should clear all the instance times that have been generated by
|
||||||
// that attribute (and hence an nsSMILTimeValueSpec), but not those from the
|
// that attribute (and hence an nsSMILTimeValueSpec), but not those from the
|
||||||
// DOM.
|
// DOM.
|
||||||
kFromDOM = 4
|
kFromDOM = 4,
|
||||||
|
|
||||||
|
// Indicates that this instance time was used as the endpoint of an interval
|
||||||
|
// that has been filtered or removed. However, since it is a dynamic time it
|
||||||
|
// should be preserved and not filtered.
|
||||||
|
kWasDynamicEndpoint = 8
|
||||||
};
|
};
|
||||||
PRUint8 mFlags; // Combination of kClearOnReset, kMayUpdate, etc.
|
PRUint8 mFlags; // Combination of kDynamic, kMayUpdate, etc.
|
||||||
|
PRPackedBool mVisited; // (mutable) Cycle tracking
|
||||||
|
|
||||||
|
// Additional reference count to determine if this instance time is currently
|
||||||
|
// used as a fixed endpoint in any intervals. Instance times that are used in
|
||||||
|
// this way should not be removed when the owning nsSMILTimedElement removes
|
||||||
|
// instance times in response to a restart or in an attempt to free up memory
|
||||||
|
// by filtering out old instance times.
|
||||||
|
//
|
||||||
|
// Instance times are only shared in a few cases, namely:
|
||||||
|
// a) early ends,
|
||||||
|
// b) zero-duration intervals, and
|
||||||
|
// c) momentarily whilst establishing new intervals and updating the current
|
||||||
|
// interval
|
||||||
|
// Hence the limited range of a PRUint16 should be more than adequate.
|
||||||
|
PRUint16 mFixedEndpointRefCnt;
|
||||||
|
|
||||||
PRUint32 mSerial; // A serial number used by the containing class to
|
PRUint32 mSerial; // A serial number used by the containing class to
|
||||||
// specify the sort order for instance times with the
|
// specify the sort order for instance times with the
|
||||||
// same mTime.
|
// same mTime.
|
||||||
PRPackedBool mVisited; // (mutable) Cycle tracking
|
|
||||||
PRPackedBool mChainEnd; // Flag to indicate that this instance time is part
|
|
||||||
// of some cyclic dependency and that in order to
|
|
||||||
// avoid infinite recursion the cycle should not be
|
|
||||||
// followed any further than this point.
|
|
||||||
|
|
||||||
nsSMILTimeValueSpec* mCreator; // The nsSMILTimeValueSpec object that created
|
nsSMILTimeValueSpec* mCreator; // The nsSMILTimeValueSpec object that created
|
||||||
// us. (currently only needed for syncbase
|
// us. (currently only needed for syncbase
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
nsSMILInterval::nsSMILInterval()
|
nsSMILInterval::nsSMILInterval()
|
||||||
:
|
:
|
||||||
|
mBeginFixed(PR_FALSE),
|
||||||
|
mEndFixed(PR_FALSE),
|
||||||
mBeginObjectChanged(PR_FALSE),
|
mBeginObjectChanged(PR_FALSE),
|
||||||
mEndObjectChanged(PR_FALSE)
|
mEndObjectChanged(PR_FALSE)
|
||||||
{
|
{
|
||||||
@ -48,19 +50,28 @@ nsSMILInterval::nsSMILInterval(const nsSMILInterval& aOther)
|
|||||||
:
|
:
|
||||||
mBegin(aOther.mBegin),
|
mBegin(aOther.mBegin),
|
||||||
mEnd(aOther.mEnd),
|
mEnd(aOther.mEnd),
|
||||||
|
mBeginFixed(PR_FALSE),
|
||||||
|
mEndFixed(PR_FALSE),
|
||||||
mBeginObjectChanged(PR_FALSE),
|
mBeginObjectChanged(PR_FALSE),
|
||||||
mEndObjectChanged(PR_FALSE)
|
mEndObjectChanged(PR_FALSE)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aOther.mDependentTimes.IsEmpty(),
|
NS_ABORT_IF_FALSE(aOther.mDependentTimes.IsEmpty(),
|
||||||
"Attempting to copy-construct an interval with dependent times, "
|
"Attempting to copy-construct an interval with dependent times, "
|
||||||
"this will lead to instance times being shared between intervals.");
|
"this will lead to instance times being shared between intervals.");
|
||||||
|
|
||||||
|
// For the time being we don't allow intervals with fixed endpoints to be
|
||||||
|
// copied since we only ever copy-construct to establish a new current
|
||||||
|
// interval. If we ever need to copy historical intervals we may need to move
|
||||||
|
// the ReleaseFixedEndpoint calls from Unlink to the dtor.
|
||||||
|
NS_ABORT_IF_FALSE(!aOther.mBeginFixed && !aOther.mEndFixed,
|
||||||
|
"Attempting to copy-construct an interval with fixed endpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSMILInterval::~nsSMILInterval()
|
nsSMILInterval::~nsSMILInterval()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mDependentTimes.IsEmpty(),
|
NS_ABORT_IF_FALSE(mDependentTimes.IsEmpty(),
|
||||||
"Destroying interval without disassociating dependent instance times. "
|
"Destroying interval without disassociating dependent instance times. "
|
||||||
"NotifyDeleting was not called.");
|
"Unlink was not called");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -76,12 +87,24 @@ nsSMILInterval::NotifyChanged(const nsSMILTimeContainer* aContainer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsSMILInterval::NotifyDeleting()
|
nsSMILInterval::Unlink(PRBool aFiltered)
|
||||||
{
|
{
|
||||||
for (PRInt32 i = mDependentTimes.Length() - 1; i >= 0; --i) {
|
for (PRInt32 i = mDependentTimes.Length() - 1; i >= 0; --i) {
|
||||||
mDependentTimes[i]->HandleDeletedInterval();
|
if (aFiltered) {
|
||||||
|
mDependentTimes[i]->HandleFilteredInterval();
|
||||||
|
} else {
|
||||||
|
mDependentTimes[i]->HandleDeletedInterval();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mDependentTimes.Clear();
|
mDependentTimes.Clear();
|
||||||
|
if (mBegin && mBeginFixed) {
|
||||||
|
mBegin->ReleaseFixedEndpoint();
|
||||||
|
}
|
||||||
|
mBegin = nsnull;
|
||||||
|
if (mEnd && mEndFixed) {
|
||||||
|
mEnd->ReleaseFixedEndpoint();
|
||||||
|
}
|
||||||
|
mEnd = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSMILInstanceTime*
|
nsSMILInstanceTime*
|
||||||
@ -104,7 +127,9 @@ void
|
|||||||
nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin)
|
nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aBegin.Time().IsResolved(),
|
NS_ABORT_IF_FALSE(aBegin.Time().IsResolved(),
|
||||||
"Attempting to set unresolved begin time on interval.");
|
"Attempting to set unresolved begin time on interval");
|
||||||
|
NS_ABORT_IF_FALSE(!mBeginFixed,
|
||||||
|
"Attempting to set begin time but the begin point is fixed");
|
||||||
|
|
||||||
if (mBegin == &aBegin)
|
if (mBegin == &aBegin)
|
||||||
return;
|
return;
|
||||||
@ -116,6 +141,9 @@ nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin)
|
|||||||
void
|
void
|
||||||
nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd)
|
nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd)
|
||||||
{
|
{
|
||||||
|
NS_ABORT_IF_FALSE(!mEndFixed,
|
||||||
|
"Attempting to set end time but the end point is fixed");
|
||||||
|
|
||||||
if (mEnd == &aEnd)
|
if (mEnd == &aEnd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -123,6 +151,28 @@ nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd)
|
|||||||
mEndObjectChanged = PR_TRUE;
|
mEndObjectChanged = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILInterval::FixBegin()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mBegin && mEnd,
|
||||||
|
"Fixing begin point on un-initialized interval");
|
||||||
|
NS_ABORT_IF_FALSE(!mBeginFixed, "Duplicate calls to FixBegin()");
|
||||||
|
mBeginFixed = PR_TRUE;
|
||||||
|
mBegin->AddRefFixedEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSMILInterval::FixEnd()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mBegin && mEnd,
|
||||||
|
"Fixing end point on un-initialized interval");
|
||||||
|
NS_ABORT_IF_FALSE(mBeginFixed,
|
||||||
|
"Fixing the end of an interval without a fixed begin");
|
||||||
|
NS_ABORT_IF_FALSE(!mEndFixed, "Duplicate calls to FixEnd()");
|
||||||
|
mEndFixed = PR_TRUE;
|
||||||
|
mEnd->AddRefFixedEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsSMILInterval::AddDependentTime(nsSMILInstanceTime& aTime)
|
nsSMILInterval::AddDependentTime(nsSMILInstanceTime& aTime)
|
||||||
{
|
{
|
||||||
@ -142,3 +192,19 @@ nsSMILInterval::RemoveDependentTime(const nsSMILInstanceTime& aTime)
|
|||||||
mDependentTimes.RemoveElementSorted(&aTime);
|
mDependentTimes.RemoveElementSorted(&aTime);
|
||||||
NS_ABORT_IF_FALSE(found, "Couldn't find instance time to delete.");
|
NS_ABORT_IF_FALSE(found, "Couldn't find instance time to delete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsSMILInterval::IsDependencyChainLink() const
|
||||||
|
{
|
||||||
|
if (!mBegin || !mEnd)
|
||||||
|
return PR_FALSE; // Not yet initialised so it can't be part of a chain
|
||||||
|
|
||||||
|
if (mDependentTimes.IsEmpty())
|
||||||
|
return PR_FALSE; // No dependents, chain end
|
||||||
|
|
||||||
|
// So we have dependents, but we're still only a link in the chain (as opposed
|
||||||
|
// to the end of the chain) if one of our endpoints is dependent on an
|
||||||
|
// interval other than ourselves.
|
||||||
|
return (mBegin->IsDependent() && mBegin->GetBaseInterval() != this) ||
|
||||||
|
(mEnd->IsDependent() && mEnd->GetBaseInterval() != this);
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user