mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 08:35:26 +00:00
merge the last green changeset on fx-team to m-c
This commit is contained in:
commit
b6faf8adf8
@ -170,6 +170,18 @@ nsApplicationAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsApplicationAccessible::FocusedChild()
|
||||
{
|
||||
if (gLastFocusedNode) {
|
||||
nsAccessible* focusedChild =
|
||||
GetAccService()->GetAccessible(gLastFocusedNode);
|
||||
if (focusedChild && focusedChild->Parent() == this)
|
||||
return focusedChild;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||
nsIAccessibleRelation **aRelation)
|
||||
|
@ -122,8 +122,10 @@ public:
|
||||
virtual PRUint32 NativeRole();
|
||||
virtual PRUint64 State();
|
||||
virtual PRUint64 NativeState();
|
||||
|
||||
virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild);
|
||||
virtual nsAccessible* FocusedChild();
|
||||
|
||||
virtual void InvalidateChildren();
|
||||
|
||||
|
@ -211,10 +211,10 @@ nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
|
||||
nsDocAccessible* document = GetAccService()->GetDocAccessible(documentNode);
|
||||
|
||||
#ifdef DEBUG_NOTIFICATIONS
|
||||
nsCOMPtr<nsISelection2> sel2(do_QueryInterface(aSelection));
|
||||
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
|
||||
|
||||
PRInt16 type = 0;
|
||||
sel2->GetType(&type);
|
||||
privSel->GetType(&type);
|
||||
|
||||
if (type == nsISelectionController::SELECTION_NORMAL ||
|
||||
type == nsISelectionController::SELECTION_SPELLCHECK) {
|
||||
@ -245,10 +245,10 @@ nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
|
||||
void
|
||||
nsCaretAccessible::ProcessSelectionChanged(nsISelection* aSelection)
|
||||
{
|
||||
nsCOMPtr<nsISelection2> sel2(do_QueryInterface(aSelection));
|
||||
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
|
||||
|
||||
PRInt16 type = 0;
|
||||
sel2->GetType(&type);
|
||||
privSel->GetType(&type);
|
||||
|
||||
if (type == nsISelectionController::SELECTION_NORMAL)
|
||||
NormalSelectionChanged(aSelection);
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "nsHyperTextAccessible.h"
|
||||
|
||||
#include "nsISelectionListener.h"
|
||||
#include "nsISelection2.h"
|
||||
|
||||
class nsRootAccessible;
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsEventStateManager.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsGUIEvent.h"
|
||||
@ -331,20 +331,18 @@ nsCoreUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
scrollToRange->SetStart(aStartNode, aStartIndex);
|
||||
scrollToRange->SetEnd(aEndNode, aEndIndex);
|
||||
|
||||
nsCOMPtr<nsISelection> selection1;
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY,
|
||||
getter_AddRefs(selection1));
|
||||
getter_AddRefs(selection));
|
||||
|
||||
nsCOMPtr<nsISelection2> selection(do_QueryInterface(selection1));
|
||||
if (selection) {
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(scrollToRange);
|
||||
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(selection));
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(scrollToRange);
|
||||
|
||||
selection->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
|
||||
PR_TRUE, aVPercent, aHPercent);
|
||||
privSel->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
|
||||
PR_TRUE, aVPercent, aHPercent);
|
||||
|
||||
selection->CollapseToStart();
|
||||
}
|
||||
selection->CollapseToStart();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
|
@ -60,7 +60,6 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIPlaintextEditor.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsTextFragment.h"
|
||||
@ -1791,8 +1790,7 @@ nsHyperTextAccessible::GetSelections(PRInt16 aType,
|
||||
}
|
||||
|
||||
if (aRanges) {
|
||||
nsCOMPtr<nsISelection2> selection2(do_QueryInterface(domSel));
|
||||
NS_ENSURE_TRUE(selection2, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(domSel));
|
||||
|
||||
nsCOMPtr<nsINode> startNode = GetNode();
|
||||
if (peditor) {
|
||||
@ -1804,7 +1802,7 @@ nsHyperTextAccessible::GetSelections(PRInt16 aType,
|
||||
|
||||
PRUint32 childCount = startNode->GetChildCount();
|
||||
nsCOMPtr<nsIDOMNode> startDOMNode(do_QueryInterface(startNode));
|
||||
nsresult rv = selection2->
|
||||
nsresult rv = privSel->
|
||||
GetRangesForIntervalCOMArray(startDOMNode, 0, startDOMNode, childCount,
|
||||
PR_TRUE, aRanges);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -47,6 +47,7 @@ DIRS = \
|
||||
attributes \
|
||||
editabletext \
|
||||
events \
|
||||
focus \
|
||||
hyperlink \
|
||||
hypertext \
|
||||
name \
|
||||
@ -103,7 +104,6 @@ _TEST_FILES =\
|
||||
test_nsIAccessNode_utils.html \
|
||||
test_nsOuterDocAccessible.html \
|
||||
test_role_nsHyperTextAcc.html \
|
||||
test_takeFocus.html \
|
||||
test_text_caret.html \
|
||||
test_textboxes.html \
|
||||
test_textboxes.xul \
|
||||
|
54
accessible/tests/mochitest/focus/Makefile.in
Normal file
54
accessible/tests/mochitest/focus/Makefile.in
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# ***** 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) 2011
|
||||
# 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 of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = accessible/focus
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES =\
|
||||
test_focusedChild.html \
|
||||
test_takeFocus.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
|
85
accessible/tests/mochitest/focus/test_focusedChild.html
Normal file
85
accessible/tests/mochitest/focus/test_focusedChild.html
Normal file
@ -0,0 +1,85 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible::focusedChild testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function openWnd()
|
||||
{
|
||||
this.eventSeq = [ new invokerChecker(EVENT_FOCUS,
|
||||
getDialogAccessible,
|
||||
this) ];
|
||||
|
||||
this.invoke = function openWnd_invoke()
|
||||
{
|
||||
this.dialog = window.openDialog("about:mozilla",
|
||||
"AboutMozilla",
|
||||
"chrome,width=600,height=600");
|
||||
}
|
||||
|
||||
this.finalCheck = function openWnd_finalCheck()
|
||||
{
|
||||
var app = getApplicationAccessible();
|
||||
is(app.focusedChild, getDialogAccessible(this),
|
||||
"Wrong focused child");
|
||||
|
||||
this.dialog.close();
|
||||
}
|
||||
|
||||
this.getID = function openWnd_getID()
|
||||
{
|
||||
return "focusedChild for application accessible";
|
||||
}
|
||||
|
||||
function getDialogAccessible(aInvoker)
|
||||
{
|
||||
return getAccessible(aInvoker.dialog.document);
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true;
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new openWnd());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=677467"
|
||||
title="focusedChild crashes on application accessible">
|
||||
Mozilla Bug 677467
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -10,12 +10,13 @@
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="states.js"></script>
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="events.js"></script>
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
@ -74,7 +74,7 @@
|
||||
};
|
||||
registerA11yEventListener(EVENT_REORDER, handler);
|
||||
|
||||
tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
|
||||
tabBrowser.loadTabs(docURIs, false, true);
|
||||
}
|
||||
|
||||
function testRelations()
|
||||
|
@ -75,7 +75,9 @@ CSRCS := \
|
||||
|
||||
libs:: $(CSRCS:.c=.$(OBJ_SUFFIX))
|
||||
|
||||
ifndef CROSS_COMPILE
|
||||
WRAP_MALLOC_CFLAGS=
|
||||
WRAP_MALLOC_LIB=
|
||||
|
||||
test$(DLL_SUFFIX): test.$(OBJ_SUFFIX) elfhack $(CSRCS:.c=.$(OBJ_SUFFIX))
|
||||
$(MKSHLIB) $(LDFLAGS) $<
|
||||
@echo ===
|
||||
@ -92,6 +94,13 @@ test$(DLL_SUFFIX): test.$(OBJ_SUFFIX) elfhack $(CSRCS:.c=.$(OBJ_SUFFIX))
|
||||
|
||||
.PRECIOUS: test$(DLL_SUFFIX)
|
||||
|
||||
CSRCS += test.c
|
||||
|
||||
GARBAGE += test$(DLL_SUFFIX) test$(DLL_SUFFIX).bak
|
||||
|
||||
libs:: test$(DLL_SUFFIX)
|
||||
|
||||
ifndef CROSS_COMPILE
|
||||
dummy: dummy.$(OBJ_SUFFIX) test$(DLL_SUFFIX)
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
@ -99,9 +108,9 @@ libs:: dummy
|
||||
# Will either crash or return exit code 1 if elfhack is broken
|
||||
LD_LIBRARY_PATH=$(CURDIR) $(CURDIR)/dummy
|
||||
|
||||
CSRCS += test.c dummy.c
|
||||
CSRCS += dummy.c
|
||||
|
||||
GARBAGE += dummy test$(DLL_SUFFIX) test$(DLL_SUFFIX).bak
|
||||
GARBAGE += dummy
|
||||
endif
|
||||
|
||||
inject:
|
||||
|
@ -45,9 +45,9 @@
|
||||
#
|
||||
|
||||
# Define an include-at-most-once flag
|
||||
#ifdef INCLUDED_CONFIG_MK
|
||||
#$(error Don't include config.mk twice!)
|
||||
#endif
|
||||
ifdef INCLUDED_CONFIG_MK
|
||||
$(error Don't include config.mk twice!)
|
||||
endif
|
||||
INCLUDED_CONFIG_MK = 1
|
||||
|
||||
EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
|
||||
|
52
configure.in
52
configure.in
@ -343,7 +343,7 @@ case "$target" in
|
||||
CPPFLAGS="-I$android_platform/usr/include $STLPORT_CPPFLAGS $CPPFLAGS"
|
||||
CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CXXFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS -static-libstdc++"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
@ -366,8 +366,8 @@ case "$target" in
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="{android_toolchain}"
|
||||
ANDROID_PLATFORM="{android_platform}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
@ -7267,6 +7267,38 @@ if test -n "$MOZ_DEBUG" -o -n "$MOZ_DEBUG_SYMBOLS"; then
|
||||
export MOZ_DEBUG_SYMBOLS
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Identical Code Folding
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(icf,
|
||||
[ --disable-icf Disable Identical Code Folding],
|
||||
MOZ_DISABLE_ICF=1,
|
||||
MOZ_DISABLE_ICF= )
|
||||
|
||||
if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF"; then
|
||||
AC_CACHE_CHECK([whether the linker supports Identical Code Folding],
|
||||
LD_SUPPORTS_ICF,
|
||||
[echo 'int foo() {return 42;}' \
|
||||
'int bar() {return 42;}' \
|
||||
'int main() {return foo() - bar();}' > conftest.${ac_ext}
|
||||
# If the linker supports ICF, foo and bar symbols will have
|
||||
# the same address
|
||||
if AC_TRY_COMMAND([${CC-cc} -o conftest${ac_exeext} $LDFLAGS -Wl,--icf=safe -ffunction-sections conftest.${ac_ext} $LIBS 1>&2]) &&
|
||||
test -s conftest${ac_exeext} &&
|
||||
objdump -t conftest${ac_exeext} | awk '{a[[$6]] = $1} END {if (a[["foo"]] && (a[["foo"]] != a[["bar"]])) { exit 1 }}'; then
|
||||
LD_SUPPORTS_ICF=yes
|
||||
else
|
||||
LD_SUPPORTS_ICF=no
|
||||
fi
|
||||
rm -rf conftest*])
|
||||
if test "$LD_SUPPORTS_ICF" = yes; then
|
||||
LDFLAGS="$LDFLAGS -Wl,--icf=safe"
|
||||
CFLAGS="$CFLAGS -ffunction-sections"
|
||||
CXXFLAGS="$CXXFLAGS -ffunction-sections"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Automatically remove dead symbols
|
||||
dnl ========================================================
|
||||
@ -7294,8 +7326,16 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -n "$MOZ_DEBUG_FLAGS"; then
|
||||
rm -rf conftest*])
|
||||
if test "$GC_SECTIONS_BREAKS_DEBUG_RANGES" = no; then
|
||||
DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
|
||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
|
||||
case "$CFLAGS" in
|
||||
*-ffunction-sections*)
|
||||
CFLAGS="$CFLAGS -fdata-sections"
|
||||
CXXFLAGS="$CXXFLAGS -fdata-sections"
|
||||
;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -7859,7 +7899,7 @@ dnl done during packaging with omnijar.
|
||||
if test "$MOZ_CHROME_FILE_FORMAT" = "omni"; then
|
||||
MOZ_OMNIJAR=1
|
||||
AC_DEFINE(MOZ_OMNIJAR)
|
||||
if test "$OS_ARCH" = "WINNT"; then
|
||||
if test "$OS_ARCH" = "WINNT" -o "$OS_ARCH" = "OS2"; then
|
||||
MOZ_CHROME_FILE_FORMAT=flat
|
||||
else
|
||||
MOZ_CHROME_FILE_FORMAT=symlink
|
||||
|
@ -108,8 +108,6 @@ XPIDLSRCS = \
|
||||
nsIDOMFormData.idl \
|
||||
nsIDOMParser.idl \
|
||||
nsIDOMSerializer.idl \
|
||||
nsISelection2.idl \
|
||||
nsISelection3.idl \
|
||||
nsISelectionController.idl \
|
||||
nsISelectionDisplay.idl \
|
||||
nsISelectionListener.idl \
|
||||
|
@ -49,7 +49,7 @@ interface nsIDOMRange;
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
[scriptable, uuid(B2C7ED59-8634-4352-9E37-5484C8B6E4E1)]
|
||||
[scriptable, uuid(5ac0cd5d-3c08-4c4c-8e70-230c433f5d5c)]
|
||||
interface nsISelection : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -165,4 +165,25 @@ interface nsISelection : nsISupports
|
||||
* Returns the whole selection into a plain text string.
|
||||
*/
|
||||
wstring toString();
|
||||
|
||||
/**
|
||||
* Modifies the selection. Note that the parameters are case-insensitive.
|
||||
*
|
||||
* @param alter can be one of { "move", "extend" }
|
||||
* - "move" collapses the selection to the end of the selection and
|
||||
* applies the movement direction/granularity to the collapsed
|
||||
* selection.
|
||||
* - "extend" leaves the start of the selection unchanged, and applies
|
||||
* movement direction/granularity to the end of the selection.
|
||||
* @param direction can be one of { "forward", "backward", "left", "right" }
|
||||
* @param granularity can be one of { "character", "word",
|
||||
* "line", "lineboundary" }
|
||||
*
|
||||
* @returns NS_ERROR_NOT_IMPLEMENTED if the granularity is "sentence",
|
||||
* "sentenceboundary", "paragraph", "paragraphboundary", or
|
||||
* "documentboundary". Returns NS_ERROR_INVALID_ARG if alter, direction,
|
||||
* or granularity has an unrecognized value.
|
||||
*/
|
||||
void modify(in DOMString alter, in DOMString direction,
|
||||
in DOMString granularity);
|
||||
};
|
||||
|
@ -1,111 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Selection code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brett Wilson <brettw@gmail.com>
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISelection.idl"
|
||||
|
||||
interface nsIDOMNode;
|
||||
interface nsIDOMRange;
|
||||
|
||||
%{C++
|
||||
#include "nsCOMArray.h"
|
||||
%}
|
||||
|
||||
[ptr] native RangeArray(nsCOMArray<nsIDOMRange>);
|
||||
|
||||
[scriptable, uuid(5d21d5fe-3691-4716-a334-4691eea54d29)]
|
||||
interface nsISelection2 : nsISelection
|
||||
{
|
||||
/**
|
||||
* Returns the type of the selection (see nsISelectionController for
|
||||
* available constants).
|
||||
*/
|
||||
readonly attribute short type;
|
||||
|
||||
/**
|
||||
* Return array of ranges intersecting with the given DOM interval.
|
||||
*/
|
||||
void GetRangesForInterval(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in boolean allowAdjacent,
|
||||
out PRUint32 resultCount,
|
||||
[retval, array, size_is(resultCount)] out nsIDOMRange results);
|
||||
|
||||
[noscript] void GetRangesForIntervalCOMArray(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in boolean allowAdjacent,
|
||||
in RangeArray results);
|
||||
|
||||
/**
|
||||
* Scrolls a region of the selection, so that it is visible in
|
||||
* the scrolled view.
|
||||
*
|
||||
* @param aRegion - the region inside the selection to scroll into view
|
||||
* (see selection region constants defined in
|
||||
* nsISelectionController).
|
||||
* @param aIsSynchronous - when true, scrolls the selection into view
|
||||
* before returning. If false, posts a request which
|
||||
* is processed at some point after the method returns.
|
||||
* @param aVPercent - how to align the frame vertically. A value of 0
|
||||
* means the frame's upper edge is aligned with the top edge
|
||||
* of the visible area. A value of 100 means the frame's
|
||||
* bottom edge is aligned with the bottom edge of
|
||||
* the visible area. For values in between, the point
|
||||
* "aVPercent" down the frame is placed at the point
|
||||
* "aVPercent" down the visible area. A value of 50 centers
|
||||
* the frame vertically. A value of -1 means move
|
||||
* the frame the minimum amount necessary in order for
|
||||
* the entire frame to be visible vertically (if possible).
|
||||
* @param aHPercent - how to align the frame horizontally. A value of 0
|
||||
* means the frame's left edge is aligned with the left
|
||||
* edge of the visible area. A value of 100 means the
|
||||
* frame's right edge is aligned with the right edge of
|
||||
* the visible area. For values in between, the point
|
||||
* "aHPercent" across the frame is placed at the point
|
||||
* "aHPercent" across the visible area. A value of 50
|
||||
* centers the frame horizontally . A value of -1 means
|
||||
* move the frame the minimum amount necessary in order
|
||||
* for the entire frame to be visible horizontally
|
||||
* (if possible).
|
||||
*/
|
||||
void scrollIntoView(in short aRegion, in boolean aIsSynchronous,
|
||||
in short aVPercent, in short aHPercent);
|
||||
};
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Selection code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Justin Lebar <justin.lebar@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(94ac0cb4-95b4-11df-8e13-0026b9792740)]
|
||||
interface nsISelection3 : nsISupports
|
||||
{
|
||||
/**
|
||||
* Modifies the selection. Note that the parameters are case-insensitive.
|
||||
*
|
||||
* @param alter can be one of { "move", "extend" }
|
||||
* - "move" collapses the selection to the end of the selection and
|
||||
* applies the movement direction/granularity to the collapsed
|
||||
* selection.
|
||||
* - "extend" leaves the start of the selection unchanged, and applies
|
||||
* movement direction/granularity to the end of the selection.
|
||||
* @param direction can be one of { "forward", "backward", "left", "right" }
|
||||
* @param granularity can be one of { "character", "word",
|
||||
* "line", "lineboundary" }
|
||||
*
|
||||
* @returns NS_ERROR_NOT_IMPLEMENTED if the granularity is "sentence",
|
||||
* "sentenceboundary", "paragraph", "paragraphboundary", or
|
||||
* "documentboundary". Returns NS_ERROR_INVALID_ARG if alter, direction,
|
||||
* or granularity has an unrecognized value.
|
||||
*/
|
||||
void modify(in DOMString alter, in DOMString direction,
|
||||
in DOMString granularity);
|
||||
|
||||
};
|
@ -38,8 +38,10 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsISelectionListener.idl"
|
||||
#include "nsIEnumerator.idl"
|
||||
#include "nsISelection.idl"
|
||||
|
||||
interface nsIDOMRange;
|
||||
interface nsIDOMNode;
|
||||
interface nsISelectionListener;
|
||||
interface nsIContent;
|
||||
|
||||
@ -50,17 +52,19 @@ class nsIPresShell;
|
||||
struct nsTextRangeStyle;
|
||||
struct nsPoint;
|
||||
#include "nsIFrame.h"
|
||||
#include "nsCOMArray.h"
|
||||
%}
|
||||
|
||||
[ptr] native nsFrameSelection(nsFrameSelection);
|
||||
[ptr] native nsIFrame(nsIFrame);
|
||||
[ptr] native nsIPresShell(nsIPresShell);
|
||||
[ptr] native RangeArray(nsCOMArray<nsIDOMRange>);
|
||||
[ref] native constTextRangeStyleRef(const nsTextRangeStyle);
|
||||
[ref] native nsPointRef(nsPoint);
|
||||
native nsDirection(nsDirection);
|
||||
|
||||
[scriptable, uuid(98552206-ad7a-4d2d-8ce3-b6fa2389298b)]
|
||||
interface nsISelectionPrivate : nsISupports
|
||||
[scriptable, uuid(1820a940-6203-4e27-bc94-fa81131722a4)]
|
||||
interface nsISelectionPrivate : nsISelection
|
||||
{
|
||||
const short ENDOFPRECEDINGLINE=0;
|
||||
const short STARTOFNEXTLINE=1;
|
||||
@ -136,5 +140,62 @@ interface nsISelectionPrivate : nsISupports
|
||||
*/
|
||||
[noscript, notxpcom] nsDirection getSelectionDirection();
|
||||
[noscript, notxpcom] void setSelectionDirection(in nsDirection aDirection);
|
||||
|
||||
/**
|
||||
* Returns the type of the selection (see nsISelectionController for
|
||||
* available constants).
|
||||
*/
|
||||
readonly attribute short type;
|
||||
|
||||
/**
|
||||
* Return array of ranges intersecting with the given DOM interval.
|
||||
*/
|
||||
void GetRangesForInterval(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in PRBool allowAdjacent,
|
||||
out PRUint32 resultCount,
|
||||
[retval, array, size_is(resultCount)] out nsIDOMRange results);
|
||||
|
||||
[noscript] void GetRangesForIntervalCOMArray(
|
||||
in nsIDOMNode beginNode, in PRInt32 beginOffset,
|
||||
in nsIDOMNode endNode, in PRInt32 endOffset,
|
||||
in PRBool allowAdjacent,
|
||||
in RangeArray results);
|
||||
|
||||
/**
|
||||
* Scrolls a region of the selection, so that it is visible in
|
||||
* the scrolled view.
|
||||
*
|
||||
* @param aRegion - the region inside the selection to scroll into view
|
||||
* (see selection region constants defined in
|
||||
* nsISelectionController).
|
||||
* @param aIsSynchronous - when true, scrolls the selection into view
|
||||
* before returning. If false, posts a request which
|
||||
* is processed at some point after the method returns.
|
||||
* @param aVPercent - how to align the frame vertically. A value of 0
|
||||
* means the frame's upper edge is aligned with the top edge
|
||||
* of the visible area. A value of 100 means the frame's
|
||||
* bottom edge is aligned with the bottom edge of
|
||||
* the visible area. For values in between, the point
|
||||
* "aVPercent" down the frame is placed at the point
|
||||
* "aVPercent" down the visible area. A value of 50 centers
|
||||
* the frame vertically. A value of -1 means move
|
||||
* the frame the minimum amount necessary in order for
|
||||
* the entire frame to be visible vertically (if possible).
|
||||
* @param aHPercent - how to align the frame horizontally. A value of 0
|
||||
* means the frame's left edge is aligned with the left
|
||||
* edge of the visible area. A value of 100 means the
|
||||
* frame's right edge is aligned with the right edge of
|
||||
* the visible area. For values in between, the point
|
||||
* "aHPercent" across the frame is placed at the point
|
||||
* "aHPercent" across the visible area. A value of 50
|
||||
* centers the frame horizontally . A value of -1 means
|
||||
* move the frame the minimum amount necessary in order
|
||||
* for the entire frame to be visible horizontally
|
||||
* (if possible).
|
||||
*/
|
||||
void scrollIntoView(in short aRegion, in boolean aIsSynchronous,
|
||||
in short aVPercent, in short aHPercent);
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsIMEStateManager.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
|
||||
@ -1071,8 +1070,7 @@ nsContentEventHandler::OnSelectionEvent(nsSelectionEvent* aEvent)
|
||||
nsCOMPtr<nsIDOMNode> endDomNode(do_QueryInterface(endNode));
|
||||
NS_ENSURE_TRUE(startDomNode && endDomNode, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(mSelection);
|
||||
NS_ENSURE_TRUE(selPrivate, NS_ERROR_UNEXPECTED);
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSelection));
|
||||
selPrivate->StartBatchChanges();
|
||||
|
||||
// Clear selection first before setting
|
||||
@ -1096,7 +1094,7 @@ nsContentEventHandler::OnSelectionEvent(nsSelectionEvent* aEvent)
|
||||
selPrivate->EndBatchChanges();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISelection2>(do_QueryInterface(mSelection))->ScrollIntoView(
|
||||
selPrivate->ScrollIntoView(
|
||||
nsISelectionController::SELECTION_FOCUS_REGION, PR_FALSE, -1, -1);
|
||||
aEvent->mSucceeded = PR_TRUE;
|
||||
return NS_OK;
|
||||
|
@ -1134,6 +1134,19 @@ NS_IMETHODIMP nsHTMLMediaElement::GetDuration(double *aDuration)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMHTMLTimeRanges seekable; */
|
||||
NS_IMETHODIMP nsHTMLMediaElement::GetSeekable(nsIDOMTimeRanges** aSeekable)
|
||||
{
|
||||
nsTimeRanges* ranges = new nsTimeRanges();
|
||||
NS_ADDREF(*aSeekable = ranges);
|
||||
|
||||
if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
|
||||
mDecoder->GetSeekable(ranges);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute boolean paused; */
|
||||
NS_IMETHODIMP nsHTMLMediaElement::GetPaused(PRBool *aPaused)
|
||||
{
|
||||
@ -1825,7 +1838,7 @@ nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
|
||||
double duration = aOriginal->GetDuration();
|
||||
if (duration >= 0) {
|
||||
decoder->SetDuration(duration);
|
||||
decoder->SetSeekable(aOriginal->GetSeekable());
|
||||
decoder->SetSeekable(aOriginal->IsSeekable());
|
||||
}
|
||||
|
||||
nsMediaStream* stream = originalStream->CloneData(decoder);
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "VideoUtils.h"
|
||||
#include "nsBuiltinDecoder.h"
|
||||
#include "nsBuiltinDecoderStateMachine.h"
|
||||
#include "nsTimeRanges.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -267,13 +268,82 @@ nsresult nsBuiltinDecoder::Play()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns PR_TRUE if aValue is inside a range of aRanges, and put the range
|
||||
* index in aIntervalIndex if it is not null.
|
||||
* If aValue is not inside a range, PR_FALSE is returned, and aIntervalIndex, if
|
||||
* not null, is set to the index of the range which ends immediatly before aValue
|
||||
* (and can be -1 if aValue is before aRanges.Start(0)).
|
||||
*/
|
||||
static PRBool IsInRanges(nsTimeRanges& aRanges, double aValue, PRInt32& aIntervalIndex) {
|
||||
PRUint32 length;
|
||||
aRanges.GetLength(&length);
|
||||
for (PRUint32 i = 0; i < length; i++) {
|
||||
double start, end;
|
||||
aRanges.Start(i, &start);
|
||||
if (start > aValue) {
|
||||
aIntervalIndex = i - 1;
|
||||
return PR_FALSE;
|
||||
}
|
||||
aRanges.End(i, &end);
|
||||
if (aValue <= end) {
|
||||
aIntervalIndex = i;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
aIntervalIndex = length - 1;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult nsBuiltinDecoder::Seek(double aTime)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
if (aTime < 0.0)
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ABORT_IF_FALSE(aTime >= 0.0, "Cannot seek to a negative value.");
|
||||
|
||||
nsTimeRanges seekable;
|
||||
nsresult res;
|
||||
PRUint32 length = 0;
|
||||
res = GetSeekable(&seekable);
|
||||
NS_ENSURE_SUCCESS(res, NS_OK);
|
||||
|
||||
seekable.GetLength(&length);
|
||||
if (!length) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the position we want to seek to is not in a seekable range, we seek
|
||||
// to the closest position in the seekable ranges instead . If two positions
|
||||
// are equaly close, we seek to the closest position from the currentTime.
|
||||
// See seeking spec, point 7 :
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#seeking
|
||||
PRInt32 range = 0;
|
||||
if (!IsInRanges(seekable, aTime, range)) {
|
||||
if (range != -1) {
|
||||
double leftBound, rightBound;
|
||||
res = seekable.End(range, &leftBound);
|
||||
NS_ENSURE_SUCCESS(res, NS_OK);
|
||||
double distanceLeft = NS_ABS(leftBound - aTime);
|
||||
|
||||
double distanceRight = -1;
|
||||
if (range + 1 < length) {
|
||||
res = seekable.Start(range+1, &rightBound);
|
||||
NS_ENSURE_SUCCESS(res, NS_OK);
|
||||
distanceRight = NS_ABS(rightBound - aTime);
|
||||
}
|
||||
|
||||
if (distanceLeft == distanceRight) {
|
||||
distanceLeft = NS_ABS(leftBound - mCurrentTime);
|
||||
distanceRight = NS_ABS(rightBound - mCurrentTime);
|
||||
}
|
||||
aTime = (distanceLeft < distanceRight) ? leftBound : rightBound;
|
||||
} else {
|
||||
// aTime is before the first range in |seekable|, the closest point we can
|
||||
// seek to is the start of the first range.
|
||||
seekable.Start(0, &aTime);
|
||||
}
|
||||
}
|
||||
|
||||
mRequestedSeekTime = aTime;
|
||||
mCurrentTime = aTime;
|
||||
@ -847,12 +917,27 @@ void nsBuiltinDecoder::SetSeekable(PRBool aSeekable)
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsBuiltinDecoder::GetSeekable()
|
||||
PRBool nsBuiltinDecoder::IsSeekable()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
return mSeekable;
|
||||
}
|
||||
|
||||
nsresult nsBuiltinDecoder::GetSeekable(nsTimeRanges* aSeekable)
|
||||
{
|
||||
//TODO : change 0.0 to GetInitialTime() when available
|
||||
double initialTime = 0.0;
|
||||
|
||||
if (IsSeekable()) {
|
||||
double end = IsInfinite() ? std::numeric_limits<double>::infinity()
|
||||
: initialTime + GetDuration();
|
||||
aSeekable->Add(initialTime, end);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return GetBuffered(aSeekable);
|
||||
}
|
||||
|
||||
void nsBuiltinDecoder::Suspend()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
@ -316,7 +316,7 @@ public:
|
||||
// Returns PR_TRUE if the media resource can seek into unbuffered ranges,
|
||||
// as set by SetSeekable(). The decoder monitor must be obtained before
|
||||
// calling this.
|
||||
virtual PRBool GetSeekable() = 0;
|
||||
virtual PRBool IsSeekable() = 0;
|
||||
|
||||
// Update the playback position. This can result in a timeupdate event
|
||||
// and an invalidate of the frame being dispatched asynchronously if
|
||||
@ -433,7 +433,9 @@ class nsBuiltinDecoder : public nsMediaDecoder
|
||||
virtual void SetSeekable(PRBool aSeekable);
|
||||
|
||||
// Return PR_TRUE if seeking is supported.
|
||||
virtual PRBool GetSeekable();
|
||||
virtual PRBool IsSeekable();
|
||||
|
||||
virtual nsresult GetSeekable(nsTimeRanges* aSeekable);
|
||||
|
||||
virtual Statistics GetStatistics();
|
||||
|
||||
|
@ -252,7 +252,7 @@ public:
|
||||
return mEndTime;
|
||||
}
|
||||
|
||||
PRBool GetSeekable() {
|
||||
PRBool IsSeekable() {
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
return mSeekable;
|
||||
}
|
||||
|
@ -291,7 +291,10 @@ public:
|
||||
virtual void SetSeekable(PRBool aSeekable) = 0;
|
||||
|
||||
// Return PR_TRUE if seeking is supported.
|
||||
virtual PRBool GetSeekable() = 0;
|
||||
virtual PRBool IsSeekable() = 0;
|
||||
|
||||
// Return the time ranges that can be seeked into.
|
||||
virtual nsresult GetSeekable(nsTimeRanges* aSeekable) = 0;
|
||||
|
||||
// Invalidate the frame.
|
||||
virtual void Invalidate();
|
||||
|
@ -326,7 +326,7 @@ nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
|
||||
mDecoder->GetStateMachine()->GetState() != nsDecoderStateMachine::DECODER_STATE_SHUTDOWN &&
|
||||
stream->GetLength() >= 0 &&
|
||||
mDecoder->GetStateMachine()->GetSeekable())
|
||||
mDecoder->GetStateMachine()->IsSeekable())
|
||||
{
|
||||
// We didn't get a duration from the index or a Content-Duration header.
|
||||
// Seek to the end of file to find the end time.
|
||||
|
@ -128,6 +128,7 @@ _TEST_FILES = \
|
||||
test_play_events_2.html \
|
||||
test_playback.html \
|
||||
test_playback_errors.html \
|
||||
test_seekable1.html \
|
||||
test_preload_actions.html \
|
||||
test_preload_attribute.html \
|
||||
test_progress.html \
|
||||
@ -259,6 +260,9 @@ _TEST_FILES += \
|
||||
contentDuration5.sjs \
|
||||
contentDuration6.sjs \
|
||||
contentDuration7.sjs \
|
||||
noContentLength.sjs \
|
||||
test_seekable2.html \
|
||||
test_seekable3.html \
|
||||
test_a4_tone.html \
|
||||
file_audio_event_adopt_iframe.html \
|
||||
test_audio_event_adopt.html \
|
||||
|
@ -146,6 +146,19 @@ function fileUriToSrc(path, mustExist) {
|
||||
return f.path;
|
||||
}
|
||||
|
||||
// Returns true if two nsTimeRanges are equal, false otherwise
|
||||
function range_equals(r1, r2) {
|
||||
if (r1.length != r2.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < r1.length; i++) {
|
||||
if (r1.start(i) != r2.start(i) || r1.end(i) != r2.end(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// These are URIs to files that we use to check that we don't leak any state
|
||||
// or other information such that script can determine stuff about a user's
|
||||
// environment. Used by test_info_leak.
|
||||
|
23
content/media/test/noContentLength.sjs
Normal file
23
content/media/test/noContentLength.sjs
Normal file
@ -0,0 +1,23 @@
|
||||
// Serve a media file without using content-range header
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
||||
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
||||
}
|
||||
fis.init(file, -1, -1, false);
|
||||
bis.setInputStream(fis);
|
||||
var bytes = bis.readBytes(bis.available());
|
||||
response.setStatusLine(request.httpVersion, 200, "Content Follows");
|
||||
response.setHeader("Content-Type", "video/ogg", false);
|
||||
response.write(bytes, bytes.length);
|
||||
bis.close();
|
||||
}
|
66
content/media/test/test_seekable1.html
Normal file
66
content/media/test/test_seekable1.html
Normal file
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test seekable member for media elements</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id='test'>
|
||||
<script class="testbody" type='application/javascript;version=1.8'>
|
||||
|
||||
let manager = new MediaTestManager;
|
||||
|
||||
function finish_test(element) {
|
||||
if (element.parentNode)
|
||||
element.parentNode.removeChild(element);
|
||||
element.src="";
|
||||
manager.finished(element.token);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test using a finite media stream, and a server supporting range requests
|
||||
{
|
||||
setup : function(element) {
|
||||
is(element.seekable.length, 0, "seekable.length should be initialy 0.");
|
||||
element.addEventListener("loadedmetadata", function() {
|
||||
is(element.seekable.length, 1, "seekable.length should be 1 for a server supporting range requests.");
|
||||
|
||||
//TODO : change this by using element.initialTime
|
||||
is(element.seekable.start(0), 0.0, "The start of the first range should be the initialTime.");
|
||||
is(element.seekable.end(0), element.duration, "The end of the first range should be the duration.")
|
||||
finish_test(element);
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function createTestArray() {
|
||||
var A = [];
|
||||
for (var k=0; k < gProgressTests.length; k++) {
|
||||
var t = new Object();
|
||||
t.setup = tests[0].setup;
|
||||
t.name = gProgressTests[k].name;
|
||||
t.type = gProgressTests[k].type;
|
||||
A.push(t);
|
||||
}
|
||||
return A;
|
||||
}
|
||||
|
||||
function startTest(test, token) {
|
||||
var elemType = /^audio/.test(test.type) ? "audio" : "video";
|
||||
var element = document.createElement(elemType);
|
||||
element.src = test.name;
|
||||
element.token = token;
|
||||
test.setup(element);
|
||||
manager.started(token);
|
||||
}
|
||||
|
||||
manager.runTests(createTestArray(), startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
37
content/media/test/test_seekable2.html
Normal file
37
content/media/test/test_seekable2.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: seek test 3</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onunload="mediaTestCleanup();">
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function on_metadataloaded() {
|
||||
var v = document.getElementById('v');
|
||||
ok(range_equals(v.seekable, v.buffered), "seekable.length should be initialy empty, or equal to buffered");
|
||||
v.addEventListener("playing", function() {
|
||||
ok(v.seekable.length > 0, "seekable.length should not be empty while playing.");
|
||||
}, false);
|
||||
v.addEventListener("ended", function() {
|
||||
is(v.seekable.length, 1, "seekable.length should be 1 at end of playback.");
|
||||
is(v.seekable.start(0), 0.0, "start of first range should 0.0");
|
||||
is(v.seekable.end(0), v.duration, "end of first range should be equal to duration");
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
|
||||
v.play();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
<video id='v'
|
||||
src='contentDuration6.sjs'
|
||||
onloadedmetadata='on_metadataloaded();'></video>
|
||||
</body>
|
||||
</html>
|
37
content/media/test/test_seekable3.html
Normal file
37
content/media/test/test_seekable3.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: seek test 3</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onunload="mediaTestCleanup();">
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function on_metadataloaded() {
|
||||
var v = document.getElementById('v');
|
||||
ok(range_equals(v.seekable, v.buffered), "seekable.length should be initialy empty");
|
||||
v.addEventListener("playing", function() {
|
||||
ok(v.seekable.length > 0, "seekable.length should not empty while playing.");
|
||||
}, false);
|
||||
v.addEventListener("ended", function() {
|
||||
is(v.seekable.length, 1, "seekable.length should be 1 at end of playback.");
|
||||
is(v.seekable.start(0), 0.0, "start of first range should 0.0");
|
||||
is(v.seekable.end(0), v.duration, "end of first range should be equal to duration");
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
|
||||
v.play();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
<video id='v'
|
||||
src='noContentLength.sjs'
|
||||
onloadedmetadata='on_metadataloaded();'></video>
|
||||
</body>
|
||||
</html>
|
@ -342,7 +342,6 @@
|
||||
#include "nsIDOMCRMFObject.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsISelection3.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsITreeSelection.h"
|
||||
@ -2919,7 +2918,6 @@ nsDOMClassInfo::Init()
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Selection, nsISelection)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsISelection)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsISelection3)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -57,7 +57,7 @@
|
||||
#endif
|
||||
%}
|
||||
|
||||
[scriptable, uuid(d8213322-46d8-47ca-a15c-2abae47ddfde)]
|
||||
[scriptable, uuid(9441effd-fbe1-4f48-aa90-1741c1e390a1)]
|
||||
interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
|
||||
{
|
||||
// error state
|
||||
@ -89,6 +89,7 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
|
||||
attribute double currentTime;
|
||||
readonly attribute double duration;
|
||||
readonly attribute boolean paused;
|
||||
readonly attribute nsIDOMTimeRanges seekable;
|
||||
readonly attribute boolean ended;
|
||||
readonly attribute boolean mozAutoplayEnabled;
|
||||
attribute boolean autoplay;
|
||||
|
@ -46,6 +46,8 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
green.png \
|
||||
test_bug290026.html \
|
||||
test_bug291780.html \
|
||||
test_bug332636.html \
|
||||
test_bug332636.html^headers^ \
|
||||
test_bug366682.html \
|
||||
|
53
editor/libeditor/html/tests/test_bug290026.html
Normal file
53
editor/libeditor/html/tests/test_bug290026.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=290026
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 290026</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/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=290026">Mozilla Bug 290026</a>
|
||||
<p id="display"></p>
|
||||
<div id="editor" contenteditable></div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 290026 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var editor = document.getElementById("editor");
|
||||
editor.innerHTML = '<p></p><ul><li>Item 1</li><li>Item 2</li></ul><p></p>';
|
||||
editor.focus();
|
||||
|
||||
addLoadEvent(function() {
|
||||
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
var lis = document.getElementsByTagName("li");
|
||||
var range = document.createRange();
|
||||
range.setStart(lis[0], 0);
|
||||
range.setEnd(lis[1], lis[1].childNodes.length);
|
||||
sel.addRange(range);
|
||||
document.execCommand("indent", false, false);
|
||||
var oneindent = '<p></p><ul style="margin-left: 40px;"><li>Item 1</li><li>Item 2</li></ul><p></p>';
|
||||
is(editor.innerHTML, oneindent, "a once indented bulleted list");
|
||||
document.execCommand("indent", false, false);
|
||||
var twoindent = '<p></p><ul style="margin-left: 80px;"><li>Item 1</li><li>Item 2</li></ul><p></p>';
|
||||
is(editor.innerHTML, twoindent, "a twice indented bulleted list");
|
||||
document.execCommand("outdent", false, false);
|
||||
todo_is(editor.innerHTML, oneindent, "outdenting a twice indented bulleted list");
|
||||
|
||||
// done
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
51
editor/libeditor/html/tests/test_bug291780.html
Normal file
51
editor/libeditor/html/tests/test_bug291780.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=291780
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 291780</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/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=291780">Mozilla Bug 291780</a>
|
||||
<p id="display"></p>
|
||||
<div id="editor" contenteditable></div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 291780 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var original = '<ul style="margin-left: 40px;"><li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li></ul>';
|
||||
var editor = document.getElementById("editor");
|
||||
editor.innerHTML = original;
|
||||
editor.focus();
|
||||
|
||||
addLoadEvent(function() {
|
||||
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
var lis = document.getElementsByTagName("li");
|
||||
var range = document.createRange();
|
||||
range.setStart(lis[1], 0);
|
||||
range.setEnd(lis[2], lis[2].childNodes.length);
|
||||
sel.addRange(range);
|
||||
document.execCommand("indent", false, false);
|
||||
var expected = '<ul style="margin-left: 40px;"><li>Item 1</li><ul><li>Item 2</li><li>Item 3</li></ul><li>Item 4</li></ul>';
|
||||
is(editor.innerHTML, expected, "indenting part of an already indented bulleted list");
|
||||
document.execCommand("outdent", false, false);
|
||||
todo_is(editor.innerHTML, original, "outdenting the partially indented part of an already indented bulleted list");
|
||||
|
||||
// done
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -85,7 +85,7 @@
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsITextServicesFilter.h"
|
||||
@ -1281,8 +1281,7 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
|
||||
if (iscollapsed)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsISelection2> sel2 = do_QueryInterface(aSpellCheckSelection, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsISelectionPrivate> privSel = do_QueryInterface(aSpellCheckSelection);
|
||||
|
||||
// see if the selection has any ranges, if not, then we can optimize checking
|
||||
// range inclusion later (we have no ranges when we are initially checking or
|
||||
@ -1347,9 +1346,9 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
|
||||
createdRange->IsPointInRange(beginNode, beginOffset, &inCreatedRange);
|
||||
if (! inCreatedRange) {
|
||||
nsCOMArray<nsIDOMRange> ranges;
|
||||
rv = sel2->GetRangesForIntervalCOMArray(beginNode, beginOffset,
|
||||
endNode, endOffset,
|
||||
PR_TRUE, &ranges);
|
||||
rv = privSel->GetRangesForIntervalCOMArray(beginNode, beginOffset,
|
||||
endNode, endOffset,
|
||||
PR_TRUE, &ranges);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (PRInt32 i = 0; i < ranges.Count(); i ++)
|
||||
RemoveRange(aSpellCheckSelection, ranges[i]);
|
||||
@ -1478,13 +1477,11 @@ mozInlineSpellChecker::IsPointInSelection(nsISelection *aSelection,
|
||||
{
|
||||
*aRange = nsnull;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISelection2> sel2 = do_QueryInterface(aSelection, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
|
||||
|
||||
nsCOMArray<nsIDOMRange> ranges;
|
||||
rv = sel2->GetRangesForIntervalCOMArray(aNode, aOffset, aNode, aOffset,
|
||||
PR_TRUE, &ranges);
|
||||
nsresult rv = privSel->GetRangesForIntervalCOMArray(aNode, aOffset, aNode, aOffset,
|
||||
PR_TRUE, &ranges);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (ranges.Count() == 0)
|
||||
|
@ -651,12 +651,15 @@ void gfxFontFamily::LocalizedName(nsAString& aLocalizedName)
|
||||
void
|
||||
gfxFontFamily::FindFontForChar(FontSearch *aMatchData)
|
||||
{
|
||||
if (!mHasStyles)
|
||||
if (!mHasStyles) {
|
||||
FindStyleVariations();
|
||||
}
|
||||
|
||||
// xxx - optimization point - keep a bit vector with the union of supported unicode ranges
|
||||
// by all fonts for this family and bail immediately if the character is not in any of
|
||||
// this family's cmaps
|
||||
if (!TestCharacterMap(aMatchData->mCh)) {
|
||||
// none of the faces in the family support the required char,
|
||||
// so bail out immediately
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate over fonts
|
||||
PRUint32 numFonts = mAvailableFonts.Length();
|
||||
@ -2610,6 +2613,22 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
// check other faces of the family
|
||||
gfxFontFamily *family = font->GetFontEntry()->Family();
|
||||
if (family && family->TestCharacterMap(aCh)) {
|
||||
FontSearch matchData(aCh, font);
|
||||
family->FindFontForChar(&matchData);
|
||||
gfxFontEntry *fe = matchData.mBestMatch;
|
||||
if (fe) {
|
||||
PRBool needsBold =
|
||||
font->GetStyle()->weight >= 600 && !fe->IsBold();
|
||||
selectedFont =
|
||||
fe->FindOrMakeFont(font->GetStyle(), needsBold);
|
||||
if (selectedFont) {
|
||||
return selectedFont.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if character is in Private Use Area, don't do matching against pref or system fonts
|
||||
|
@ -482,7 +482,8 @@ public:
|
||||
mFaceNamesInitialized(PR_FALSE),
|
||||
mHasStyles(PR_FALSE),
|
||||
mIsSimpleFamily(PR_FALSE),
|
||||
mIsBadUnderlineFamily(PR_FALSE)
|
||||
mIsBadUnderlineFamily(PR_FALSE),
|
||||
mCharacterMapInitialized(PR_FALSE)
|
||||
{ }
|
||||
|
||||
virtual ~gfxFontFamily() { }
|
||||
@ -544,10 +545,28 @@ public:
|
||||
// read in cmaps for all the faces
|
||||
void ReadCMAP() {
|
||||
PRUint32 i, numFonts = mAvailableFonts.Length();
|
||||
// called from RunLoader BEFORE CheckForSimpleFamily so that there cannot
|
||||
// be any NULL entries in mAvailableFonts
|
||||
for (i = 0; i < numFonts; i++)
|
||||
mAvailableFonts[i]->ReadCMAP();
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
gfxFontEntry *fe = mAvailableFonts[i];
|
||||
if (!fe) {
|
||||
continue;
|
||||
}
|
||||
fe->ReadCMAP();
|
||||
mCharacterMap.Union(fe->mCharacterMap);
|
||||
}
|
||||
mCharacterMap.Compact();
|
||||
mCharacterMapInitialized = PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool TestCharacterMap(PRUint32 aCh) {
|
||||
if (!mCharacterMapInitialized) {
|
||||
ReadCMAP();
|
||||
}
|
||||
return mCharacterMap.test(aCh);
|
||||
}
|
||||
|
||||
void ResetCharacterMap() {
|
||||
mCharacterMap.reset();
|
||||
mCharacterMapInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
// mark this family as being in the "bad" underline offset blacklist
|
||||
@ -590,12 +609,14 @@ protected:
|
||||
|
||||
nsString mName;
|
||||
nsTArray<nsRefPtr<gfxFontEntry> > mAvailableFonts;
|
||||
gfxSparseBitSet mCharacterMap;
|
||||
PRPackedBool mOtherFamilyNamesInitialized;
|
||||
PRPackedBool mHasOtherFamilyNames;
|
||||
PRPackedBool mFaceNamesInitialized;
|
||||
PRPackedBool mHasStyles;
|
||||
PRPackedBool mIsSimpleFamily;
|
||||
PRPackedBool mIsBadUnderlineFamily;
|
||||
PRPackedBool mCharacterMapInitialized;
|
||||
|
||||
enum {
|
||||
// for "simple" families, the faces are stored in mAvailableFonts
|
||||
|
@ -313,7 +313,7 @@ gfxFontUtils::ReadCMAPTableFormat12(const PRUint8 *aBuf, PRUint32 aLength,
|
||||
prevEndCharCode = endCharCode;
|
||||
}
|
||||
|
||||
aCharacterMap.mBlocks.Compact();
|
||||
aCharacterMap.Compact();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -391,7 +391,7 @@ gfxFontUtils::ReadCMAPTableFormat4(const PRUint8 *aBuf, PRUint32 aLength,
|
||||
}
|
||||
}
|
||||
|
||||
aCharacterMap.mBlocks.Compact();
|
||||
aCharacterMap.Compact();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -165,8 +165,6 @@ public:
|
||||
Block *block = mBlocks[blockIndex];
|
||||
if (!block) {
|
||||
block = new Block;
|
||||
if (NS_UNLIKELY(!block)) // OOM
|
||||
return;
|
||||
mBlocks[blockIndex] = block;
|
||||
}
|
||||
block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)] |= 1 << (aIndex & 0x7);
|
||||
@ -201,9 +199,6 @@ public:
|
||||
fullBlock = PR_TRUE;
|
||||
|
||||
block = new Block(fullBlock ? 0xFF : 0);
|
||||
|
||||
if (NS_UNLIKELY(!block)) // OOM
|
||||
return;
|
||||
mBlocks[i] = block;
|
||||
|
||||
if (fullBlock)
|
||||
@ -279,7 +274,44 @@ public:
|
||||
for (i = 0; i < mBlocks.Length(); i++)
|
||||
mBlocks[i] = nsnull;
|
||||
}
|
||||
|
||||
|
||||
// set this bitset to the union of its current contents and another
|
||||
void Union(const gfxSparseBitSet& aBitset) {
|
||||
// ensure mBlocks is large enough
|
||||
PRUint32 blockCount = aBitset.mBlocks.Length();
|
||||
if (blockCount > mBlocks.Length()) {
|
||||
PRUint32 needed = blockCount - mBlocks.Length();
|
||||
nsAutoPtr<Block> *blocks = mBlocks.AppendElements(needed);
|
||||
if (NS_UNLIKELY(!blocks)) { // OOM
|
||||
return;
|
||||
}
|
||||
}
|
||||
// for each block that may be present in aBitset...
|
||||
for (PRUint32 i = 0; i < blockCount; ++i) {
|
||||
// if it is missing (implicitly empty), just skip
|
||||
if (!aBitset.mBlocks[i]) {
|
||||
continue;
|
||||
}
|
||||
// if the block is missing in this set, just copy the other
|
||||
if (!mBlocks[i]) {
|
||||
mBlocks[i] = new Block(*aBitset.mBlocks[i]);
|
||||
continue;
|
||||
}
|
||||
// else set existing block to the union of both
|
||||
PRUint32 *dst = reinterpret_cast<PRUint32*>(mBlocks[i]->mBits);
|
||||
const PRUint32 *src =
|
||||
reinterpret_cast<const PRUint32*>(aBitset.mBlocks[i]->mBits);
|
||||
for (PRUint32 j = 0; j < BLOCK_SIZE / 4; ++j) {
|
||||
dst[j] |= src[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compact() {
|
||||
mBlocks.Compact();
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray< nsAutoPtr<Block> > mBlocks;
|
||||
};
|
||||
|
||||
|
@ -106,10 +106,12 @@ public:
|
||||
|
||||
virtual ~gfxMixedFontFamily() { }
|
||||
|
||||
void AddFontEntry(gfxFontEntry *aFontEntry) {
|
||||
void AddFontEntry(gfxFontEntry *aFontEntry)
|
||||
{
|
||||
nsRefPtr<gfxFontEntry> fe = aFontEntry;
|
||||
mAvailableFonts.AppendElement(fe);
|
||||
aFontEntry->SetFamily(this);
|
||||
ResetCharacterMap();
|
||||
}
|
||||
|
||||
void ReplaceFontEntry(gfxFontEntry *aOldFontEntry, gfxFontEntry *aNewFontEntry)
|
||||
@ -123,9 +125,10 @@ public:
|
||||
// other reference to it except from its family
|
||||
mAvailableFonts[i] = aNewFontEntry;
|
||||
aNewFontEntry->SetFamily(this);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ResetCharacterMap();
|
||||
}
|
||||
|
||||
void RemoveFontEntry(gfxFontEntry *aFontEntry)
|
||||
@ -136,9 +139,10 @@ public:
|
||||
if (fe == aFontEntry) {
|
||||
aFontEntry->SetFamily(nsnull);
|
||||
mAvailableFonts.RemoveElementAt(i);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ResetCharacterMap();
|
||||
}
|
||||
|
||||
// temp method to determine if all proxies are loaded
|
||||
|
@ -45,9 +45,9 @@
|
||||
#
|
||||
|
||||
# Define an include-at-most-once flag
|
||||
#ifdef INCLUDED_CONFIG_MK
|
||||
#$(error Don't include config.mk twice!)
|
||||
#endif
|
||||
ifdef INCLUDED_CONFIG_MK
|
||||
$(error Don't include config.mk twice!)
|
||||
endif
|
||||
INCLUDED_CONFIG_MK = 1
|
||||
|
||||
EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
|
||||
|
@ -334,7 +334,7 @@ case "$target" in
|
||||
CPPFLAGS="-I$android_platform/usr/include $STLPORT_CPPFLAGS $CPPFLAGS"
|
||||
CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CXXFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS -static-libstdc++"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
@ -357,8 +357,8 @@ case "$target" in
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="{android_toolchain}"
|
||||
ANDROID_PLATFORM="{android_platform}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
|
@ -50,7 +50,7 @@ var FOCUS = 1;
|
||||
|
||||
function testCollapsed(id, vPercent, startAt, expected) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var selection = window.getSelection().QueryInterface(Components.interfaces.nsISelection2);
|
||||
var selection = window.getSelection().QueryInterface(Components.interfaces.nsISelectionPrivate);
|
||||
|
||||
var c = document.getElementById("c" + id);
|
||||
var target = document.getElementById("target" + id);
|
||||
|
@ -48,9 +48,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelection3.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISelectionListener.h"
|
||||
#include "nsIComponentManager.h"
|
||||
@ -181,9 +178,7 @@ static RangeData sEmptyData(nsnull);
|
||||
// This ensures that nsFrameSelection is never deleted before its
|
||||
// nsTypedSelections.
|
||||
|
||||
class nsTypedSelection : public nsISelection2,
|
||||
public nsISelection3,
|
||||
public nsISelectionPrivate,
|
||||
class nsTypedSelection : public nsISelectionPrivate,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
@ -192,10 +187,8 @@ public:
|
||||
virtual ~nsTypedSelection();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTypedSelection, nsISelection)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTypedSelection, nsISelectionPrivate)
|
||||
NS_DECL_NSISELECTION
|
||||
NS_DECL_NSISELECTION2
|
||||
NS_DECL_NSISELECTION3
|
||||
NS_DECL_NSISELECTIONPRIVATE
|
||||
|
||||
// utility methods for scrolling the selection into view
|
||||
@ -3451,8 +3444,6 @@ DOMCI_DATA(Selection, nsTypedSelection)
|
||||
// QueryInterface implementation for nsTypedSelection
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTypedSelection)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISelection)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISelection2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISelection3)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISelectionPrivate)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISelection)
|
||||
|
@ -332,11 +332,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
selection.addRange(range8);
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 8, 10);
|
||||
var sel2 = selection.QueryInterface(Components.interfaces.nsISelection2);
|
||||
ok(sel2, "Test 17 - QIed to instance of nsISelection2 interface");
|
||||
var privSel = selection.QueryInterface(Components.interfaces.nsISelectionPrivate);
|
||||
ok(privSel, "Test 17 - QIed to instance of nsISelection2 interface");
|
||||
var numResults = {};
|
||||
var results = sel2.GetRangesForInterval(testNode, 8, testNode, 10,
|
||||
false, numResults);
|
||||
var results = privSel.GetRangesForInterval(testNode, 8, testNode, 10,
|
||||
false, numResults);
|
||||
intervalChecker.check(17, results);
|
||||
|
||||
// Test 18. Check GetRangesForInterval returns correct results.
|
||||
@ -344,16 +344,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.addExpected(testNode, 6, 8);
|
||||
intervalChecker.addExpected(testNode, 10, 12);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 8, testNode, 10,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 8, testNode, 10,
|
||||
true, numResults);
|
||||
intervalChecker.check(18, results);
|
||||
|
||||
// Test 19. Check GetRangesForInterval returns correct results.
|
||||
// Part 3 - Test interval not selected.
|
||||
intervalChecker.reset();
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 14, testNode, 16,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 14, testNode, 16,
|
||||
true, numResults);
|
||||
intervalChecker.check(19, results);
|
||||
|
||||
// Test 20. Check GetRangesForInterval returns correct results.
|
||||
@ -364,8 +364,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 0, 10);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 5, testNode, 7,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 5, testNode, 7,
|
||||
true, numResults);
|
||||
intervalChecker.check(20, results);
|
||||
|
||||
// Test 21. Check GetRangesForInterval returns correct results.
|
||||
@ -376,8 +376,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 6, 8);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 5, testNode, 9,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 5, testNode, 9,
|
||||
true, numResults);
|
||||
intervalChecker.check(21, results);
|
||||
|
||||
// Test 22. Check GetRangesForInterval returns correct results.
|
||||
@ -388,8 +388,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 8, 10);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 6, testNode, 8,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 6, testNode, 8,
|
||||
true, numResults);
|
||||
intervalChecker.check(22, results);
|
||||
|
||||
// Test 23. Check GetRangesForInterval returns correct results.
|
||||
@ -397,8 +397,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
// the range array, and adjacencies not permitted.
|
||||
intervalChecker.reset();
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 6, testNode, 8,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 6, testNode, 8,
|
||||
false, numResults);
|
||||
intervalChecker.check(23, results);
|
||||
|
||||
// Test 24. Check GetRangesForInterval returns correct results.
|
||||
@ -406,8 +406,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
// and adjacencies permitted.
|
||||
intervalChecker.addExpected(testNode, 8, 10);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 10, testNode, 12,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 10, testNode, 12,
|
||||
true, numResults);
|
||||
intervalChecker.check(24, results);
|
||||
|
||||
// Test 25. Check GetRangesForInterval returns correct results.
|
||||
@ -415,8 +415,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
// and adjacencies not permitted.
|
||||
intervalChecker.reset();
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 10, testNode, 12,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 10, testNode, 12,
|
||||
false, numResults);
|
||||
intervalChecker.check(25, results);
|
||||
|
||||
// Test 26. Check GetRangesForInterval returns correct results.
|
||||
@ -426,16 +426,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
selection.addRange(range4);
|
||||
intervalChecker.addExpected(testNode, 11, 11);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
true, numResults);
|
||||
intervalChecker.check(26, results);
|
||||
|
||||
// Test 27. Check GetRangesForInterval returns correct results.
|
||||
// Part 11 - Test interval is equal to a collapsed range at position 0
|
||||
// in the range array, and adjacencies not permitted.
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
false, numResults);
|
||||
intervalChecker.check(27, results);
|
||||
|
||||
// Test 28. Check GetRangesForInterval returns correct results.
|
||||
@ -445,16 +445,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
selection.addRange(range2);
|
||||
selection.addRange(range4);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
true, numResults);
|
||||
intervalChecker.check(28, results);
|
||||
|
||||
// Test 29. Check GetRangesForInterval returns correct results.
|
||||
// Part 13 - Test interval is equal to a collapsed range at end of the
|
||||
// range array, and adjacencies not permitted.
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 11, testNode, 11,
|
||||
false, numResults);
|
||||
intervalChecker.check(29, results);
|
||||
|
||||
// Test 30. Check GetRangesForInterval returns correct results.
|
||||
@ -465,8 +465,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 6, 8);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 7, testNode, 7,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 7, testNode, 7,
|
||||
true, numResults);
|
||||
intervalChecker.check(30, results);
|
||||
|
||||
// Test 31. Check GetRangesForInterval returns correct results.
|
||||
@ -481,8 +481,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 8, 8);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 8, testNode, 8,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 8, testNode, 8,
|
||||
false, numResults);
|
||||
intervalChecker.check(31, results);
|
||||
|
||||
// Test 32. Check GetRangesForInterval returns correct results.
|
||||
@ -490,16 +490,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
// at either endpoint of the selection's range array,
|
||||
// adjacencies allowed.
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 8, testNode, 8,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 8, testNode, 8,
|
||||
true, numResults);
|
||||
intervalChecker.check(32, results);
|
||||
|
||||
// Test 33. Check GetRangesForInterval returns correct results.
|
||||
// Part 17 - Test interval contains a collapsed range which is not
|
||||
// stored at either endpoint of the selection's range array.
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 7, testNode, 9,
|
||||
false, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 7, testNode, 9,
|
||||
false, numResults);
|
||||
intervalChecker.check(33, results);
|
||||
|
||||
// Test 34. Check GetRangesForInterval returns correct results.
|
||||
@ -507,8 +507,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 5, 7);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 2, testNode, 6,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 2, testNode, 6,
|
||||
true, numResults);
|
||||
intervalChecker.check(34, results);
|
||||
|
||||
// Test 35. Check GetRangesForInterval returns correct results.
|
||||
@ -518,8 +518,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=348681
|
||||
intervalChecker.reset();
|
||||
intervalChecker.addExpected(testNode, 10, 12);
|
||||
numResults = {};
|
||||
results = sel2.GetRangesForInterval(testNode, 11, testNode, 13,
|
||||
true, numResults);
|
||||
results = privSel.GetRangesForInterval(testNode, 11, testNode, 13,
|
||||
true, numResults);
|
||||
intervalChecker.check(35, results);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -540,9 +540,10 @@ nsMathMLmtableOuterFrame::GetRowFrameAt(nsPresContext* aPresContext,
|
||||
// Negative indices mean to find upwards from the end.
|
||||
if (aRowIndex < 0) {
|
||||
aRowIndex = rowCount + aRowIndex;
|
||||
} else {
|
||||
// aRowIndex is 1-based, so convert it to a 0-based index
|
||||
--aRowIndex;
|
||||
}
|
||||
// aRowIndex is 1-based, so convert it to a 0-based index
|
||||
--aRowIndex;
|
||||
|
||||
// if our inner table says that the index is valid, find the row now
|
||||
if (0 <= aRowIndex && aRowIndex <= rowCount) {
|
||||
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>mtable align attribute: negative rownumber</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
|
||||
<mtable align="axis 3"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>b</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd> <mtd><mi>e</mi></mtd> <mtd><mi>f</mi></mtd></mtr> <mtr><mtd><mi>g</mi></mtd> <mtd><mi>h</mi></mtd> <mtd><mi>i</mi></mtd></mtr></mtable><mo>=</mo>
|
||||
<mtable align="axis 1"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>b</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd> <mtd><mi>e</mi></mtd> <mtd><mi>f</mi></mtd></mtr> <mtr><mtd><mi>g</mi></mtd> <mtd><mi>h</mi></mtd> <mtd><mi>i</mi></mtd></mtr></mtable></mrow></math>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
15
layout/reftests/mathml/mtable-align-negative-rownumber.html
Normal file
15
layout/reftests/mathml/mtable-align-negative-rownumber.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>mtable align attribute: negative rownumber</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
|
||||
<mtable align="axis -1"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>b</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd> <mtd><mi>e</mi></mtd> <mtd><mi>f</mi></mtd></mtr> <mtr><mtd><mi>g</mi></mtd> <mtd><mi>h</mi></mtd> <mtd><mi>i</mi></mtd></mtr></mtable><mo>=</mo>
|
||||
<mtable align="axis 1"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>b</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd> <mtd><mi>e</mi></mtd> <mtd><mi>f</mi></mtd></mtr> <mtr><mtd><mi>g</mi></mtd> <mtd><mi>h</mi></mtd> <mtd><mi>i</mi></mtd></mtr></mtable></mrow></math>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -26,6 +26,7 @@ fails-if(winWidget) == mfenced-10.html mfenced-10-ref.html
|
||||
== table-width-1.xhtml table-width-1-ref.xhtml
|
||||
== underbar-width-1.xhtml underbar-width-1-ref.xhtml
|
||||
== mathml-type-supported.xhtml mathml-type-supported-ref.xml
|
||||
== mtable-align-negative-rownumber.html mtable-align-negative-rownumber-ref.html
|
||||
!= embellished-op-1-1.html embellished-op-1-1-ref.html
|
||||
!= embellished-op-1-2.html embellished-op-1-2-ref.html
|
||||
!= embellished-op-1-3.html embellished-op-1-3-ref.html
|
||||
|
@ -92,6 +92,7 @@ nsFontFaceLoader::nsFontFaceLoader(gfxProxyFontEntry *aProxy, nsIURI *aFontURI,
|
||||
: mFontEntry(aProxy), mFontURI(aFontURI), mFontSet(aFontSet),
|
||||
mChannel(aChannel)
|
||||
{
|
||||
mFontFamily = aProxy->Family();
|
||||
}
|
||||
|
||||
nsFontFaceLoader::~nsFontFaceLoader()
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxProxyFontEntry> mFontEntry;
|
||||
nsRefPtr<gfxFontFamily> mFontFamily;
|
||||
nsCOMPtr<nsIURI> mFontURI;
|
||||
nsRefPtr<nsUserFontSet> mFontSet;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -573,7 +573,7 @@ WebSocketChannel::WebSocketChannel() :
|
||||
mStopOnClose(NS_OK),
|
||||
mServerCloseCode(CLOSE_ABNORMAL),
|
||||
mScriptCloseCode(0),
|
||||
mFragmentOpcode(0),
|
||||
mFragmentOpcode(kContinuation),
|
||||
mFragmentAccumulator(0),
|
||||
mBuffered(0),
|
||||
mBufferSize(16384),
|
||||
@ -863,7 +863,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
||||
// Only the first frame has a non zero op code: Make sure we don't see a
|
||||
// first frame while some old fragments are open
|
||||
if ((mFragmentAccumulator != 0) && (opcode != kContinuation)) {
|
||||
LOG(("WebSocketHeandler:: nested fragments\n"));
|
||||
LOG(("WebSocketChannel:: nested fragments\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
@ -871,6 +871,14 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
||||
LOG(("WebSocketChannel:: Accumulating Fragment %lld\n", payloadLength));
|
||||
|
||||
if (opcode == kContinuation) {
|
||||
|
||||
// Make sure this continuation fragment isn't the first fragment
|
||||
if (mFragmentOpcode == kContinuation) {
|
||||
LOG(("WebSocketHeandler:: continuation code in first fragment\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
// For frag > 1 move the data body back on top of the headers
|
||||
// so we have contiguous stream of data
|
||||
NS_ABORT_IF_FALSE(mFramePtr + framingLength == payload,
|
||||
@ -890,6 +898,8 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
||||
avail += mFragmentAccumulator;
|
||||
mFragmentAccumulator = 0;
|
||||
opcode = mFragmentOpcode;
|
||||
// reset to detect if next message illegally starts with continuation
|
||||
mFragmentOpcode = kContinuation;
|
||||
} else {
|
||||
opcode = kContinuation;
|
||||
mFragmentAccumulator += payloadLength;
|
||||
|
@ -257,11 +257,11 @@ DEFAULT_GMAKE_FLAGS += \
|
||||
CPU_ARCH="$(TARGET_CPU)" \
|
||||
$(NULL)
|
||||
|
||||
# Android has pthreads integrated into -lc, so OS_LIBS is set to nothing
|
||||
# Android has pthreads integrated into -lc, so OS_PTHREAD is set to nothing
|
||||
ifeq ($(OS_TARGET), Android)
|
||||
DEFAULT_GMAKE_FLAGS += \
|
||||
OS_RELEASE="2.6" \
|
||||
OS_LIBS= \
|
||||
OS_PTHREAD= \
|
||||
STANDARDS_CFLAGS="-std=gnu89" \
|
||||
DSO_CFLAGS="$(CFLAGS) -DCHECK_FORK_GETPID -DRTLD_NOLOAD=0 -DANDROID_VERSION=$(ANDROID_VERSION) -include $(ABS_topsrcdir)/security/manager/android_stub.h" \
|
||||
DSO_LDOPTS="-shared $(LDFLAGS) $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB) " \
|
||||
|
@ -1294,7 +1294,7 @@ BookmarksTracker.prototype = {
|
||||
this._log.debug("Restore succeeded: wiping server and other clients.");
|
||||
Weave.Service.resetClient([this.name]);
|
||||
Weave.Service.wipeServer([this.name]);
|
||||
Weave.Service.prepCommand("wipeEngine", [this.name]);
|
||||
Clients.sendCommand("wipeEngine", [this.name]);
|
||||
break;
|
||||
case "bookmarks-restore-failed":
|
||||
this._log.debug("Tracking all items on failed import.");
|
||||
|
@ -48,6 +48,7 @@ Cu.import("resource://services-sync/ext/StringBundle.js");
|
||||
Cu.import("resource://services-sync/record.js");
|
||||
Cu.import("resource://services-sync/resource.js");
|
||||
Cu.import("resource://services-sync/util.js");
|
||||
Cu.import("resource://services-sync/main.js");
|
||||
|
||||
const CLIENTS_TTL = 1814400; // 21 days
|
||||
const CLIENTS_TTL_REFRESH = 604800; // 7 days
|
||||
@ -107,41 +108,6 @@ ClientEngine.prototype = {
|
||||
return stats;
|
||||
},
|
||||
|
||||
// Remove any commands for the local client and mark it for upload
|
||||
clearCommands: function clearCommands() {
|
||||
delete this.localCommands;
|
||||
this._tracker.addChangedID(this.localID);
|
||||
},
|
||||
|
||||
// Send a command+args pair to each remote client
|
||||
sendCommand: function sendCommand(command, args) {
|
||||
// Helper to determine if the client already has this command
|
||||
let notDupe = function(other) other.command != command ||
|
||||
JSON.stringify(other.args) != JSON.stringify(args);
|
||||
|
||||
// Package the command/args pair into an object
|
||||
let action = {
|
||||
command: command,
|
||||
args: args,
|
||||
};
|
||||
|
||||
// Send the command to each remote client
|
||||
for (let [id, client] in Iterator(this._store._remoteClients)) {
|
||||
// Set the action to be a new commands array if none exists
|
||||
if (client.commands == null)
|
||||
client.commands = [action];
|
||||
// Add the new action if there are no duplicates
|
||||
else if (client.commands.every(notDupe))
|
||||
client.commands.push(action);
|
||||
// Must have been a dupe.. skip!
|
||||
else
|
||||
continue;
|
||||
|
||||
this._log.trace("Client " + id + " got a new action: " + [command, args]);
|
||||
this._tracker.addChangedID(id);
|
||||
}
|
||||
},
|
||||
|
||||
get localID() {
|
||||
// Generate a random GUID id we don't have one
|
||||
let localID = Svc.Prefs.get("client.GUID", "");
|
||||
@ -221,6 +187,149 @@ ClientEngine.prototype = {
|
||||
|
||||
// Neither try again nor error; we're going to delete it.
|
||||
return SyncEngine.kRecoveryStrategy.ignore;
|
||||
},
|
||||
|
||||
/**
|
||||
* A hash of valid commands that the client knows about. The key is a command
|
||||
* and the value is a hash containing information about the command such as
|
||||
* number of arguments and description.
|
||||
*/
|
||||
_commands: {
|
||||
resetAll: { args: 0, desc: "Clear temporary local data for all engines" },
|
||||
resetEngine: { args: 1, desc: "Clear temporary local data for engine" },
|
||||
wipeAll: { args: 0, desc: "Delete all client data for all engines" },
|
||||
wipeEngine: { args: 1, desc: "Delete all client data for engine" },
|
||||
logout: { args: 0, desc: "Log out client" }
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove any commands for the local client and mark it for upload.
|
||||
*/
|
||||
clearCommands: function clearCommands() {
|
||||
delete this.localCommands;
|
||||
this._tracker.addChangedID(this.localID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a command+args pair to a specific client.
|
||||
*
|
||||
* @param command Command string
|
||||
* @param args Array of arguments/data for command
|
||||
* @param clientId Client to send command to
|
||||
*/
|
||||
_sendCommandToClient: function sendCommandToClient(command, args, clientId) {
|
||||
this._log.trace("Sending " + command + " to " + clientId);
|
||||
|
||||
let client = this._store._remoteClients[clientId];
|
||||
if (!client) {
|
||||
throw new Error("Unknown remote client ID: '" + clientId + "'.");
|
||||
}
|
||||
|
||||
// notDupe compares two commands and returns if they are not equal.
|
||||
let notDupe = function(other) {
|
||||
return other.command != command || !Utils.deepEquals(other.args, args);
|
||||
};
|
||||
|
||||
let action = {
|
||||
command: command,
|
||||
args: args,
|
||||
};
|
||||
|
||||
if (!client.commands) {
|
||||
client.commands = [action];
|
||||
}
|
||||
// Add the new action if there are no duplicates.
|
||||
else if (client.commands.every(notDupe)) {
|
||||
client.commands.push(action);
|
||||
}
|
||||
// It must be a dupe. Skip.
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
this._log.trace("Client " + clientId + " got a new action: " + [command, args]);
|
||||
this._tracker.addChangedID(clientId);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the local client has any remote commands and perform them.
|
||||
*
|
||||
* @return false to abort sync
|
||||
*/
|
||||
processIncomingCommands: function processIncomingCommands() {
|
||||
return this._notify("clients:process-commands", "", function() {
|
||||
let commands = this.localCommands;
|
||||
|
||||
// Immediately clear out the commands as we've got them locally.
|
||||
this.clearCommands();
|
||||
|
||||
// Process each command in order.
|
||||
for each ({command: command, args: args} in commands) {
|
||||
this._log.debug("Processing command: " + command + "(" + args + ")");
|
||||
|
||||
let engines = [args[0]];
|
||||
switch (command) {
|
||||
case "resetAll":
|
||||
engines = null;
|
||||
// Fallthrough
|
||||
case "resetEngine":
|
||||
Weave.Service.resetClient(engines);
|
||||
break;
|
||||
case "wipeAll":
|
||||
engines = null;
|
||||
// Fallthrough
|
||||
case "wipeEngine":
|
||||
Weave.Service.wipeClient(engines);
|
||||
break;
|
||||
case "logout":
|
||||
Weave.Service.logout();
|
||||
return false;
|
||||
default:
|
||||
this._log.debug("Received an unknown command: " + command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
})();
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates and sends a command to a client or all clients.
|
||||
*
|
||||
* Calling this does not actually sync the command data to the server. If the
|
||||
* client already has the command/args pair, it won't receive a duplicate
|
||||
* command.
|
||||
*
|
||||
* @param command
|
||||
* Command to invoke on remote clients
|
||||
* @param args
|
||||
* Array of arguments to give to the command
|
||||
* @param clientId
|
||||
* Client ID to send command to. If undefined, send to all remote
|
||||
* clients.
|
||||
*/
|
||||
sendCommand: function sendCommand(command, args, clientId) {
|
||||
let commandData = this._commands[command];
|
||||
// Don't send commands that we don't know about.
|
||||
if (!commandData) {
|
||||
this._log.error("Unknown command to send: " + command);
|
||||
return;
|
||||
}
|
||||
// Don't send a command with the wrong number of arguments.
|
||||
else if (!args || args.length != commandData.args) {
|
||||
this._log.error("Expected " + commandData.args + " args for '" +
|
||||
command + "', but got " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientId) {
|
||||
this._sendCommandToClient(command, args, clientId);
|
||||
} else {
|
||||
for (let id in this._store._remoteClients) {
|
||||
this._sendCommandToClient(command, args, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Dan Mills <thunder@mozilla.com>
|
||||
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||
* Richard Newman <rnewman@mozilla.com>
|
||||
* Allison Naaktgeboren <ally@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -253,8 +254,8 @@ HistoryStore.prototype = {
|
||||
}
|
||||
|
||||
let cb = Async.makeSyncCallback();
|
||||
let onPlace = function onPlace(result, placeInfo) {
|
||||
if (!Components.isSuccessCode(result)) {
|
||||
let updatePlacesCallback = {
|
||||
handleError: function handleError(resultCode, placeInfo) {
|
||||
failed.push(placeInfo.guid);
|
||||
}
|
||||
};
|
||||
@ -263,7 +264,7 @@ HistoryStore.prototype = {
|
||||
cb();
|
||||
};
|
||||
Svc.Obs.add(TOPIC_UPDATEPLACES_COMPLETE, onComplete);
|
||||
this._asyncHistory.updatePlaces(records, onPlace);
|
||||
this._asyncHistory.updatePlaces(records, updatePlacesCallback);
|
||||
Async.waitForSyncCallback(cb);
|
||||
return failed;
|
||||
},
|
||||
|
@ -1461,10 +1461,9 @@ WeaveSvc.prototype = {
|
||||
break;
|
||||
}
|
||||
|
||||
// Process the incoming commands if we have any
|
||||
if (Clients.localCommands) {
|
||||
try {
|
||||
if (!(this.processCommands())) {
|
||||
if (!(Clients.processIncomingCommands())) {
|
||||
Status.sync = ABORT_SYNC_COMMAND;
|
||||
throw "aborting sync, process commands said so";
|
||||
}
|
||||
@ -1817,20 +1816,22 @@ WeaveSvc.prototype = {
|
||||
*/
|
||||
wipeRemote: function WeaveSvc_wipeRemote(engines)
|
||||
this._catch(this._notify("wipe-remote", "", function() {
|
||||
// Make sure stuff gets uploaded
|
||||
// Make sure stuff gets uploaded.
|
||||
this.resetClient(engines);
|
||||
|
||||
// Clear out any server data
|
||||
// Clear out any server data.
|
||||
this.wipeServer(engines);
|
||||
|
||||
// Only wipe the engines provided
|
||||
if (engines)
|
||||
engines.forEach(function(e) this.prepCommand("wipeEngine", [e]), this);
|
||||
// Tell the remote machines to wipe themselves
|
||||
else
|
||||
this.prepCommand("wipeAll", []);
|
||||
// Only wipe the engines provided.
|
||||
if (engines) {
|
||||
engines.forEach(function(e) Clients.sendCommand("wipeEngine", [e]), this);
|
||||
}
|
||||
// Tell the remote machines to wipe themselves.
|
||||
else {
|
||||
Clients.sendCommand("wipeAll", []);
|
||||
}
|
||||
|
||||
// Make sure the changed clients get updated
|
||||
// Make sure the changed clients get updated.
|
||||
Clients.sync();
|
||||
}))(),
|
||||
|
||||
@ -1871,104 +1872,16 @@ WeaveSvc.prototype = {
|
||||
engine.resetClient();
|
||||
}))(),
|
||||
|
||||
/**
|
||||
* A hash of valid commands that the client knows about. The key is a command
|
||||
* and the value is a hash containing information about the command such as
|
||||
* number of arguments and description.
|
||||
*/
|
||||
_commands: [
|
||||
["resetAll", 0, "Clear temporary local data for all engines"],
|
||||
["resetEngine", 1, "Clear temporary local data for engine"],
|
||||
["wipeAll", 0, "Delete all client data for all engines"],
|
||||
["wipeEngine", 1, "Delete all client data for engine"],
|
||||
["logout", 0, "Log out client"],
|
||||
].reduce(function WeaveSvc__commands(commands, entry) {
|
||||
commands[entry[0]] = {};
|
||||
for (let [i, attr] in Iterator(["args", "desc"]))
|
||||
commands[entry[0]][attr] = entry[i + 1];
|
||||
return commands;
|
||||
}, {}),
|
||||
|
||||
/**
|
||||
* Check if the local client has any remote commands and perform them.
|
||||
*
|
||||
* @return False to abort sync
|
||||
*/
|
||||
processCommands: function WeaveSvc_processCommands()
|
||||
this._notify("process-commands", "", function() {
|
||||
// Immediately clear out the commands as we've got them locally
|
||||
let commands = Clients.localCommands;
|
||||
Clients.clearCommands();
|
||||
|
||||
// Process each command in order
|
||||
for each ({command: command, args: args} in commands) {
|
||||
this._log.debug("Processing command: " + command + "(" + args + ")");
|
||||
|
||||
let engines = [args[0]];
|
||||
switch (command) {
|
||||
case "resetAll":
|
||||
engines = null;
|
||||
// Fallthrough
|
||||
case "resetEngine":
|
||||
this.resetClient(engines);
|
||||
break;
|
||||
case "wipeAll":
|
||||
engines = null;
|
||||
// Fallthrough
|
||||
case "wipeEngine":
|
||||
this.wipeClient(engines);
|
||||
break;
|
||||
case "logout":
|
||||
this.logout();
|
||||
return false;
|
||||
default:
|
||||
this._log.debug("Received an unknown command: " + command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
})(),
|
||||
|
||||
/**
|
||||
* Prepare to send a command to each remote client. Calling this doesn't
|
||||
* actually sync the command data to the server. If the client already has
|
||||
* the command/args pair, it won't get a duplicate action.
|
||||
*
|
||||
* @param command
|
||||
* Command to invoke on remote clients
|
||||
* @param args
|
||||
* Array of arguments to give to the command
|
||||
*/
|
||||
prepCommand: function WeaveSvc_prepCommand(command, args) {
|
||||
let commandData = this._commands[command];
|
||||
// Don't send commands that we don't know about
|
||||
if (commandData == null) {
|
||||
this._log.error("Unknown command to send: " + command);
|
||||
return;
|
||||
}
|
||||
// Don't send a command with the wrong number of arguments
|
||||
else if (args == null || args.length != commandData.args) {
|
||||
this._log.error("Expected " + commandData.args + " args for '" +
|
||||
command + "', but got " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the command to all remote clients
|
||||
this._log.debug("Sending clients: " + [command, args, commandData.desc]);
|
||||
Clients.sendCommand(command, args);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch storage info from the server.
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* String specifying what info to fetch from the server. Must be one
|
||||
* of the INFO_* values. See Sync Storage Server API spec for details.
|
||||
* @param callback
|
||||
* Callback function with signature (error, data) where `data' is
|
||||
* the return value from the server already parsed as JSON.
|
||||
*
|
||||
*
|
||||
* @return RESTRequest instance representing the request, allowing callers
|
||||
* to cancel the request.
|
||||
*/
|
||||
|
@ -239,6 +239,216 @@ add_test(function test_client_name_change() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_send_command() {
|
||||
_("Verifies _sendCommandToClient puts commands in the outbound queue.");
|
||||
|
||||
let store = Clients._store;
|
||||
let tracker = Clients._tracker;
|
||||
let remoteId = Utils.makeGUID();
|
||||
let rec = new ClientsRec("clients", remoteId);
|
||||
|
||||
store.create(rec);
|
||||
let remoteRecord = store.createRecord(remoteId, "clients");
|
||||
|
||||
let action = "testCommand";
|
||||
let args = ["foo", "bar"];
|
||||
|
||||
Clients._sendCommandToClient(action, args, remoteId);
|
||||
|
||||
let newRecord = store._remoteClients[remoteId];
|
||||
do_check_neq(newRecord, undefined);
|
||||
do_check_eq(newRecord.commands.length, 1);
|
||||
|
||||
let command = newRecord.commands[0];
|
||||
do_check_eq(command.command, action);
|
||||
do_check_eq(command.args.length, 2);
|
||||
do_check_eq(command.args, args);
|
||||
|
||||
do_check_neq(tracker.changedIDs[remoteId], undefined);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_command_validation() {
|
||||
_("Verifies that command validation works properly.");
|
||||
|
||||
let store = Clients._store;
|
||||
|
||||
let testCommands = [
|
||||
["resetAll", [], true ],
|
||||
["resetAll", ["foo"], false],
|
||||
["resetEngine", ["tabs"], true ],
|
||||
["resetEngine", [], false],
|
||||
["wipeAll", [], true ],
|
||||
["wipeAll", ["foo"], false],
|
||||
["wipeEngine", ["tabs"], true ],
|
||||
["wipeEngine", [], false],
|
||||
["logout", [], true ],
|
||||
["logout", ["foo"], false],
|
||||
["__UNKNOWN__", [], false]
|
||||
];
|
||||
|
||||
for each (let [action, args, expectedResult] in testCommands) {
|
||||
let remoteId = Utils.makeGUID();
|
||||
let rec = new ClientsRec("clients", remoteId);
|
||||
|
||||
store.create(rec);
|
||||
store.createRecord(remoteId, "clients");
|
||||
|
||||
Clients.sendCommand(action, args, remoteId);
|
||||
|
||||
let newRecord = store._remoteClients[remoteId];
|
||||
do_check_neq(newRecord, undefined);
|
||||
|
||||
if (expectedResult) {
|
||||
_("Ensuring command is sent: " + action);
|
||||
do_check_eq(newRecord.commands.length, 1);
|
||||
|
||||
let command = newRecord.commands[0];
|
||||
do_check_eq(command.command, action);
|
||||
do_check_eq(command.args, args);
|
||||
|
||||
do_check_neq(Clients._tracker, undefined);
|
||||
do_check_neq(Clients._tracker.changedIDs[remoteId], undefined);
|
||||
} else {
|
||||
_("Ensuring command is scrubbed: " + action);
|
||||
do_check_eq(newRecord.commands, undefined);
|
||||
|
||||
if (store._tracker) {
|
||||
do_check_eq(Clients._tracker[remoteId], undefined);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_command_duplication() {
|
||||
_("Ensures duplicate commands are detected and not added");
|
||||
|
||||
let store = Clients._store;
|
||||
let remoteId = Utils.makeGUID();
|
||||
let rec = new ClientsRec("clients", remoteId);
|
||||
store.create(rec);
|
||||
store.createRecord(remoteId, "clients");
|
||||
|
||||
let action = "resetAll";
|
||||
let args = [];
|
||||
|
||||
Clients.sendCommand(action, args, remoteId);
|
||||
Clients.sendCommand(action, args, remoteId);
|
||||
|
||||
let newRecord = store._remoteClients[remoteId];
|
||||
do_check_eq(newRecord.commands.length, 1);
|
||||
|
||||
_("Check variant args length");
|
||||
newRecord.commands = [];
|
||||
|
||||
action = "resetEngine";
|
||||
Clients.sendCommand(action, [{ x: "foo" }], remoteId);
|
||||
Clients.sendCommand(action, [{ x: "bar" }], remoteId);
|
||||
|
||||
_("Make sure we spot a real dupe argument.");
|
||||
Clients.sendCommand(action, [{ x: "bar" }], remoteId);
|
||||
|
||||
do_check_eq(newRecord.commands.length, 2);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_command_invalid_client() {
|
||||
_("Ensures invalid client IDs are caught");
|
||||
|
||||
let id = Utils.makeGUID();
|
||||
let error;
|
||||
|
||||
try {
|
||||
Clients.sendCommand("wipeAll", [], id);
|
||||
} catch (ex) {
|
||||
error = ex;
|
||||
}
|
||||
|
||||
do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_process_incoming_commands() {
|
||||
_("Ensures local commands are executed");
|
||||
|
||||
Clients.localCommands = [{ command: "logout", args: [] }];
|
||||
|
||||
let ev = "weave:service:logout:finish";
|
||||
|
||||
var handler = function() {
|
||||
Svc.Obs.remove(ev, handler);
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
Svc.Obs.add(ev, handler);
|
||||
|
||||
// logout command causes processIncomingCommands to return explicit false.
|
||||
do_check_false(Clients.processIncomingCommands());
|
||||
});
|
||||
|
||||
add_test(function test_command_sync() {
|
||||
_("Ensure that commands are synced across clients.");
|
||||
Svc.Prefs.set("clusterURL", "http://localhost:8080/");
|
||||
Svc.Prefs.set("username", "foo");
|
||||
|
||||
generateNewKeys();
|
||||
|
||||
let global = new ServerWBO('global',
|
||||
{engines: {clients: {version: Clients.version,
|
||||
syncID: Clients.syncID}}});
|
||||
let coll = new ServerCollection();
|
||||
let clientwbo = coll.wbos[Clients.localID] = new ServerWBO(Clients.localID);
|
||||
let server = httpd_setup({
|
||||
"/1.1/foo/storage/meta/global": global.handler(),
|
||||
"/1.1/foo/storage/clients": coll.handler()
|
||||
});
|
||||
let remoteId = Utils.makeGUID();
|
||||
let remotewbo = coll.wbos[remoteId] = new ServerWBO(remoteId);
|
||||
server.registerPathHandler(
|
||||
"/1.1/foo/storage/clients/" + Clients.localID, clientwbo.handler());
|
||||
server.registerPathHandler(
|
||||
"/1.1/foo/storage/clients/" + remoteId, remotewbo.handler());
|
||||
|
||||
_("Create remote client record");
|
||||
let rec = new ClientsRec("clients", remoteId);
|
||||
Clients._store.create(rec);
|
||||
let remoteRecord = Clients._store.createRecord(remoteId, "clients");
|
||||
Clients.sendCommand("wipeAll", []);
|
||||
|
||||
let clientRecord = Clients._store._remoteClients[remoteId];
|
||||
do_check_neq(clientRecord, undefined);
|
||||
do_check_eq(clientRecord.commands.length, 1);
|
||||
|
||||
try {
|
||||
Clients.sync();
|
||||
do_check_neq(clientwbo.payload, undefined);
|
||||
do_check_true(Clients.lastRecordUpload > 0);
|
||||
|
||||
do_check_neq(remotewbo.payload, undefined);
|
||||
|
||||
Svc.Prefs.set("client.GUID", remoteId);
|
||||
Clients._resetClient();
|
||||
do_check_eq(Clients.localID, remoteId);
|
||||
Clients.sync();
|
||||
do_check_neq(Clients.localCommands, undefined);
|
||||
do_check_eq(Clients.localCommands.length, 1);
|
||||
|
||||
let command = Clients.localCommands[0];
|
||||
do_check_eq(command.command, "wipeAll");
|
||||
do_check_eq(command.args.length, 0);
|
||||
|
||||
} finally {
|
||||
Svc.Prefs.resetBranch("");
|
||||
Records.clearCache();
|
||||
server.stop(run_next_test);
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
initTestLogging("Trace");
|
||||
Log4Moz.repository.getLogger("Sync.Engine.Clients").level = Log4Moz.Level.Trace;
|
||||
|
21
testing/tps/INSTALL.sh
Normal file → Executable file
21
testing/tps/INSTALL.sh
Normal file → Executable file
@ -55,13 +55,27 @@ fi
|
||||
|
||||
# install TPS
|
||||
cd ${CWD}
|
||||
python setup.py develop
|
||||
python setup.py install
|
||||
|
||||
if [ "$?" -gt 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONFIG="`find ${VIRTUAL_ENV} -name config.json.in`"
|
||||
NEWCONFIG=${CONFIG:0:${#CONFIG}-3}
|
||||
|
||||
cd "../../services/sync/tests/tps"
|
||||
TESTDIR="`pwd`"
|
||||
|
||||
cd "../../tps"
|
||||
EXTDIR="`pwd`"
|
||||
|
||||
sed 's|__TESTDIR__|'"${TESTDIR}"'|' "${CONFIG}" | sed 's|__EXTENSIONDIR__|'"${EXTDIR}"'|' > "${NEWCONFIG}"
|
||||
rm ${CONFIG}
|
||||
|
||||
echo
|
||||
echo "***********************************************************************"
|
||||
echo
|
||||
echo "To run TPS, activate the virtualenv using:"
|
||||
echo " source ${TARGET}/${BIN_NAME}"
|
||||
@ -69,3 +83,8 @@ echo "then execute tps using:"
|
||||
echo " runtps --binary=/path/to/firefox"
|
||||
echo
|
||||
echo "See runtps --help for all options"
|
||||
echo
|
||||
echo "To change your TPS config, please edit the file: "
|
||||
echo "${NEWCONFIG}"
|
||||
echo
|
||||
echo "***********************************************************************"
|
||||
|
7
testing/tps/config/README.txt
Normal file
7
testing/tps/config/README.txt
Normal file
@ -0,0 +1,7 @@
|
||||
To edit the TPS configuration, do not edit config.json.in in the tree.
|
||||
Instead, edit config.json inside your virtualenv; it will be located at
|
||||
something like:
|
||||
|
||||
(linux): /path/to/virtualenv/lib/python2.6/site-packages/tps-0.2.40-py2.6.egg/tps/config.json
|
||||
(win): /path/to/virtualenv/Lib/site-packages/tps-0.2.40-py2.6.egg/tps/config.json
|
||||
|
@ -18,6 +18,8 @@
|
||||
},
|
||||
"platform": "win32",
|
||||
"os": "win7",
|
||||
"es": "localhost:9200"
|
||||
"es": "localhost:9200",
|
||||
"testdir": "__TESTDIR__",
|
||||
"extensiondir": "__EXTENSIONDIR__"
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ setup(name='tps',
|
||||
keywords='',
|
||||
author='Jonathan Griffin',
|
||||
author_email='jgriffin@mozilla.com',
|
||||
url='http://hg.mozilla.org/services/tps',
|
||||
url='http://hg.mozilla.org/services/services-central',
|
||||
license='MPL',
|
||||
dependency_links = [
|
||||
"http://people.mozilla.org/~jgriffin/packages/"
|
||||
@ -72,4 +72,7 @@ setup(name='tps',
|
||||
[console_scripts]
|
||||
runtps = tps.cli:main
|
||||
""",
|
||||
data_files=[
|
||||
('tps', ['config/config.json.in']),
|
||||
],
|
||||
)
|
||||
|
@ -38,6 +38,7 @@
|
||||
import json
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from threading import RLock
|
||||
@ -76,7 +77,7 @@ def main():
|
||||
"will be searched;")
|
||||
parser.add_option("--configfile",
|
||||
action = "store", type = "string", dest = "configfile",
|
||||
default = "config.json",
|
||||
default = None,
|
||||
help = "path to the config file to use "
|
||||
"[default: %default]")
|
||||
parser.add_option("--pulsefile",
|
||||
@ -86,15 +87,33 @@ def main():
|
||||
"json format that you want to inject into the monitor")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
configfile = options.configfile
|
||||
if configfile is None:
|
||||
if os.environ.get('VIRTUAL_ENV'):
|
||||
configfile = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
else:
|
||||
raise Exception("Unable to find config.json in a VIRTUAL_ENV; you must "
|
||||
"specify a config file using the --configfile option")
|
||||
|
||||
# load the config file
|
||||
f = open(options.configfile, 'r')
|
||||
f = open(configfile, 'r')
|
||||
configcontent = f.read()
|
||||
f.close()
|
||||
config = json.loads(configcontent)
|
||||
|
||||
rlock = RLock()
|
||||
|
||||
extensionDir = os.path.join(os.getcwd(), "..", "..", "services", "sync", "tps")
|
||||
extensionDir = config.get("extensiondir")
|
||||
if not extensionDir or extensionDir == '__EXTENSIONDIR__':
|
||||
extensionDir = os.path.join(os.getcwd(), "..", "..", "services", "sync", "tps")
|
||||
else:
|
||||
if sys.platform == 'win32':
|
||||
# replace msys-style paths with proper Windows paths
|
||||
import re
|
||||
m = re.match('^\/\w\/', extensionDir)
|
||||
if m:
|
||||
extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
|
||||
extensionDir = extensionDir.replace("/", "\\")
|
||||
|
||||
if options.binary is None:
|
||||
# If no binary is specified, start the pulse build monitor, and wait
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsDependentString.h"
|
||||
#include "nsPromiseFlatString.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
@ -85,7 +85,7 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
|
||||
if (aAlertListener)
|
||||
cpc->AddRemoteAlertObserver(nsDependentString(aAlertCookie), aAlertListener);
|
||||
cpc->AddRemoteAlertObserver(PromiseFlatString(aAlertCookie), aAlertListener);
|
||||
|
||||
cpc->SendShowAlertNotification(nsAutoString(aImageUrl),
|
||||
nsAutoString(aAlertTitle),
|
||||
|
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
* Allison Naaktgeboren <ally@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -566,8 +567,13 @@ public:
|
||||
nsCOMPtr<mozIPlaceInfo> place =
|
||||
new PlaceInfo(mPlace.placeId, mPlace.guid, uri.forget(), mPlace.title,
|
||||
-1, visits);
|
||||
if (NS_SUCCEEDED(mResult)) {
|
||||
(void)mCallback->HandleResult(place);
|
||||
}
|
||||
else {
|
||||
(void)mCallback->HandleError(mResult, place);
|
||||
}
|
||||
|
||||
(void)mCallback->OnComplete(mResult, place);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -122,20 +122,31 @@ interface mozIPlaceInfo : nsISupports
|
||||
/**
|
||||
* @status EXPERIMENTAL
|
||||
*/
|
||||
[scriptable,function, uuid(3b97ca3c-5ea8-424f-b429-797477c52302)]
|
||||
[scriptable, uuid(eb0b406f-8f57-4f2b-b0da-8883684b138a)]
|
||||
interface mozIVisitInfoCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called for each visit added, title change, or guid change when passed to
|
||||
* mozIAsyncHistory::updatePlaces.
|
||||
* Called when the given mozIPlaceInfo object could not be processed.
|
||||
*
|
||||
* @param aResultCode
|
||||
* nsresult of the change indicating success or failure reason.
|
||||
* nsresult indicating the failure reason.
|
||||
* @param aPlaceInfo
|
||||
* The information that was being entered into the database.
|
||||
*/
|
||||
void onComplete(in nsresult aResultCode,
|
||||
in mozIPlaceInfo aPlaceInfo);
|
||||
void handleError(in nsresult aResultCode,
|
||||
in mozIPlaceInfo aPlaceInfo);
|
||||
|
||||
/**
|
||||
* Called for each visit added, title change, or guid change when passed to
|
||||
* mozIAsyncHistory::updatePlaces. If more than one operation is done for
|
||||
* a given visit, only one callback will be given (i.e. title change and
|
||||
* add visit).
|
||||
*
|
||||
* @param aPlaceInfo
|
||||
* The information that was being entered into the database.
|
||||
*/
|
||||
void handleResult(in mozIPlaceInfo aPlaceInfo);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -152,9 +163,8 @@ interface mozIAsyncHistory : nsISupports
|
||||
* The mozIPlaceInfo object[s] containing the information to store or
|
||||
* update. This can be a single object, or an array of objects.
|
||||
* @param [optional] aCallback
|
||||
* Callback to be notified for each visit addition, title change, or
|
||||
* guid change. If more than one operation is done for a given visit,
|
||||
* only one callback will be given (i.e. title change and add visit).
|
||||
* A mozIVisitInfoCallback object which consists of callbacks to be
|
||||
* notified for successful and/or failed changes.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG
|
||||
* - Passing in NULL for aPlaceInfo.
|
||||
|
@ -159,6 +159,38 @@ function do_check_title_for_uri(aURI,
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default callback handler throws when success is unexpected.
|
||||
*
|
||||
* @param handleErrorFunc
|
||||
* The error handling function
|
||||
*/
|
||||
function expectHandleError(handleErrorFunc)
|
||||
{
|
||||
return {
|
||||
handleError: handleErrorFunc,
|
||||
handleResult: function handleResult(aPlaceInfo) {
|
||||
do_throw("Unexpected success.");
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Default callback handler throws when failure is unexpected.
|
||||
*
|
||||
* @param handleResultFunc
|
||||
* The success handling function
|
||||
*/
|
||||
|
||||
function expectHandleResult(handleResultFunc)
|
||||
{
|
||||
return {
|
||||
handleError: function handleError(aResultCode, aPlacesInfo) {
|
||||
do_throw("Unexpected error: " + aResultCode);
|
||||
},
|
||||
handleResult: handleResultFunc
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
@ -422,7 +454,7 @@ function test_non_addable_uri_errors()
|
||||
});
|
||||
|
||||
let callbackCount = 0;
|
||||
gHistory.updatePlaces(places, function(aResultCode, aPlaceInfo) {
|
||||
gHistory.updatePlaces(places, expectHandleError(function(aResultCode, aPlaceInfo) {
|
||||
do_log_info("Checking '" + aPlaceInfo.uri.spec + "'");
|
||||
do_check_eq(aResultCode, Cr.NS_ERROR_INVALID_ARG);
|
||||
do_check_false(gGlobalHistory.isVisited(aPlaceInfo.uri));
|
||||
@ -431,7 +463,7 @@ function test_non_addable_uri_errors()
|
||||
if (++callbackCount == places.length) {
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_duplicate_guid_errors()
|
||||
@ -446,8 +478,7 @@ function test_duplicate_guid_errors()
|
||||
};
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
let badPlace = {
|
||||
@ -459,13 +490,13 @@ function test_duplicate_guid_errors()
|
||||
};
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(badPlace.uri));
|
||||
gHistory.updatePlaces(badPlace, function(aResultCode, aPlaceInfo) {
|
||||
gHistory.updatePlaces(badPlace, expectHandleError(function(aResultCode, aPlaceInfo) {
|
||||
do_check_eq(aResultCode, Cr.NS_ERROR_STORAGE_CONSTRAINT);
|
||||
do_check_false(gGlobalHistory.isVisited(badPlace.uri));
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function test_invalid_referrerURI_ignored()
|
||||
@ -481,8 +512,7 @@ function test_invalid_referrerURI_ignored()
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
do_check_false(gGlobalHistory.isVisited(place.visits[0].referrerURI));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
|
||||
@ -501,7 +531,7 @@ function test_invalid_referrerURI_ignored()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_nonnsIURI_referrerURI_ignored()
|
||||
@ -516,8 +546,7 @@ function test_nonnsIURI_referrerURI_ignored()
|
||||
place.visits[0].referrerURI = place.uri.spec + "_nonnsIURI";
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
|
||||
@ -533,7 +562,7 @@ function test_nonnsIURI_referrerURI_ignored()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_invalid_sessionId_ignored()
|
||||
@ -548,8 +577,7 @@ function test_invalid_sessionId_ignored()
|
||||
place.visits[0].sessionId = -1;
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
|
||||
@ -569,7 +597,7 @@ function test_invalid_sessionId_ignored()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_unstored_sessionId_ignored()
|
||||
@ -595,8 +623,7 @@ function test_unstored_sessionId_ignored()
|
||||
place.visits[0].sessionId = maxSessionId + 10;
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
|
||||
@ -618,7 +645,7 @@ function test_unstored_sessionId_ignored()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@ -638,11 +665,10 @@ function test_old_referrer_ignored()
|
||||
// First we must add our referrer to the history so that it is not ignored
|
||||
// as being invalid.
|
||||
do_check_false(gGlobalHistory.isVisited(referrerPlace.uri));
|
||||
gHistory.updatePlaces(referrerPlace, function(aResultCode, aPlaceInfo) {
|
||||
gHistory.updatePlaces(referrerPlace, expectHandleResult(function(aPlaceInfo) {
|
||||
// Now that the referrer is added, we can add a page with a valid
|
||||
// referrer to determine if the recency of the referrer is taken into
|
||||
// account.
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
do_check_true(gGlobalHistory.isVisited(referrerPlace.uri));
|
||||
|
||||
let visitInfo = new VisitInfo();
|
||||
@ -655,8 +681,7 @@ function test_old_referrer_ignored()
|
||||
};
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult (function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
// Though the visit will not contain the referrer, we must examine the
|
||||
@ -674,8 +699,8 @@ function test_old_referrer_ignored()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function test_place_id_ignored()
|
||||
@ -688,8 +713,7 @@ function test_place_id_ignored()
|
||||
};
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
let placeId = aPlaceInfo.placeId;
|
||||
@ -704,15 +728,18 @@ function test_place_id_ignored()
|
||||
};
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(badPlace.uri));
|
||||
gHistory.updatePlaces(badPlace, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(badPlace, {
|
||||
handleResult: function handleResult(aPlaceInfo) {
|
||||
do_check_neq(aPlaceInfo.placeId, placeId);
|
||||
do_check_true(gGlobalHistory.isVisited(badPlace.uri));
|
||||
|
||||
do_check_neq(aPlaceInfo.placeId, placeId);
|
||||
do_check_true(gGlobalHistory.isVisited(badPlace.uri));
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
},
|
||||
handleError: function handleError(aResultCode) {
|
||||
do_throw("Unexpected error: " + aResultCode);
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_observer_topic_dispatched_when_complete()
|
||||
@ -737,21 +764,28 @@ function test_observer_topic_dispatched_when_complete()
|
||||
do_check_false(gGlobalHistory.isVisited(places[0].uri));
|
||||
do_check_false(gGlobalHistory.isVisited(places[1].uri));
|
||||
|
||||
const EXPECTED_COUNT = 3;
|
||||
let callbackCount = 0;
|
||||
const EXPECTED_COUNT_SUCCESS = 2;
|
||||
const EXPECTED_COUNT_FAILURE = 1;
|
||||
let callbackCountSuccess = 0;
|
||||
let callbackCountFailure = 0;
|
||||
|
||||
gHistory.updatePlaces(places, function(aResultCode, aPlaceInfo) {
|
||||
let checker = PlacesUtils.history.canAddURI(aPlaceInfo.uri) ?
|
||||
do_check_true : do_check_false;
|
||||
checker(Components.isSuccessCode(aResultCode));
|
||||
callbackCount++;
|
||||
gHistory.updatePlaces(places, {
|
||||
handleResult: function handleResult(aPlaceInfo) {
|
||||
let checker = PlacesUtils.history.canAddURI(aPlaceInfo.uri) ?
|
||||
do_check_true : do_check_false;
|
||||
callbackCountSuccess++;
|
||||
},
|
||||
handleError: function handleError(aResultCode, aPlaceInfo) {
|
||||
callbackCountFailure++;
|
||||
}
|
||||
});
|
||||
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
do_check_eq(aTopic, TOPIC_UPDATEPLACES_COMPLETE);
|
||||
do_check_eq(callbackCount, EXPECTED_COUNT);
|
||||
do_check_eq(callbackCountSuccess, EXPECTED_COUNT_SUCCESS);
|
||||
do_check_eq(callbackCountFailure, EXPECTED_COUNT_FAILURE);
|
||||
Services.obs.removeObserver(observer, TOPIC_UPDATEPLACES_COMPLETE);
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
},
|
||||
@ -775,8 +809,7 @@ function test_add_visit()
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
let callbackCount = 0;
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
// Check mozIPlaceInfo properties.
|
||||
@ -790,14 +823,14 @@ function test_add_visit()
|
||||
let visit = visits[0];
|
||||
do_check_eq(visit.visitDate, VISIT_TIME);
|
||||
do_check_true(visit.transitionType >= TRANSITION_LINK &&
|
||||
visit.transitionType <= TRANSITION_FRAMED_LINK);
|
||||
visit.transitionType <= TRANSITION_FRAMED_LINK);
|
||||
do_check_true(visit.referrerURI === null);
|
||||
|
||||
// For TRANSITION_EMBED visits, many properties will always be zero or
|
||||
// undefined.
|
||||
if (visit.transitionType == TRANSITION_EMBED) {
|
||||
// Check mozIPlaceInfo properties.
|
||||
do_check_eq(aPlaceInfo.placeId, 0);
|
||||
do_check_eq(aPlaceInfo.placeId, 0, '//');
|
||||
do_check_eq(aPlaceInfo.guid, null);
|
||||
|
||||
// Check mozIVisitInfo properties.
|
||||
@ -819,7 +852,7 @@ function test_add_visit()
|
||||
if (++callbackCount == place.visits.length) {
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_properties_saved()
|
||||
@ -842,8 +875,7 @@ function test_properties_saved()
|
||||
}
|
||||
|
||||
let callbackCount = 0;
|
||||
gHistory.updatePlaces(places, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(places, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
let visit = aPlaceInfo.visits[0];
|
||||
@ -915,7 +947,7 @@ function test_properties_saved()
|
||||
if (++callbackCount == places.length) {
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_guid_saved()
|
||||
@ -930,15 +962,13 @@ function test_guid_saved()
|
||||
do_check_valid_places_guid(place.guid);
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
do_check_eq(aPlaceInfo.guid, place.guid);
|
||||
do_check_guid_for_uri(uri, place.guid);
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_referrer_saved()
|
||||
@ -961,8 +991,7 @@ function test_referrer_saved()
|
||||
|
||||
let callbackCount = 0;
|
||||
let referrerSessionId;
|
||||
gHistory.updatePlaces(places, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(places, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
let visit = aPlaceInfo.visits[0];
|
||||
@ -993,7 +1022,7 @@ function test_referrer_saved()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_sessionId_saved()
|
||||
@ -1007,8 +1036,7 @@ function test_sessionId_saved()
|
||||
place.visits[0].sessionId = 3;
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
let uri = aPlaceInfo.uri;
|
||||
do_check_true(gGlobalHistory.isVisited(uri));
|
||||
|
||||
@ -1028,7 +1056,7 @@ function test_sessionId_saved()
|
||||
stmt.finalize();
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function test_guid_change_saved()
|
||||
@ -1042,19 +1070,17 @@ function test_guid_change_saved()
|
||||
};
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
|
||||
// Then, change the guid with visits.
|
||||
place.guid = "_GUIDCHANGE_";
|
||||
place.visits = [new VisitInfo()];
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_guid_for_uri(place.uri, place.guid);
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function test_title_change_saved()
|
||||
@ -1069,35 +1095,31 @@ function test_title_change_saved()
|
||||
};
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
|
||||
// Now, make sure the empty string clears the title.
|
||||
place.title = "";
|
||||
place.visits = [new VisitInfo()];
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_title_for_uri(place.uri, null);
|
||||
|
||||
// Then, change the title with visits.
|
||||
place.title = "title change";
|
||||
place.visits = [new VisitInfo()];
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_title_for_uri(place.uri, place.title);
|
||||
|
||||
// Lastly, check that the title is cleared if we set it to null.
|
||||
place.title = null;
|
||||
place.visits = [new VisitInfo()];
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_title_for_uri(place.uri, place.title);
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function test_no_title_does_not_clear_title()
|
||||
@ -1113,19 +1135,16 @@ function test_no_title_does_not_clear_title()
|
||||
};
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
// Now, make sure that not specifying a title does not clear it.
|
||||
delete place.title;
|
||||
place.visits = [new VisitInfo()];
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_title_for_uri(place.uri, TITLE);
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function test_title_change_notifies()
|
||||
@ -1229,8 +1248,7 @@ function test_referrer_sessionId_persists()
|
||||
// First we add the referrer visit, and then the main visit with referrer
|
||||
// attached. We ensure that the sessionId is maintained across the updates.
|
||||
do_check_false(gGlobalHistory.isVisited(referrerPlace.uri));
|
||||
gHistory.updatePlaces(referrerPlace, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(referrerPlace, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(referrerPlace.uri));
|
||||
|
||||
let sessionId = aPlaceInfo.visits[0].sessionId;
|
||||
@ -1245,15 +1263,52 @@ function test_referrer_sessionId_persists()
|
||||
place.visits[0].referrerURI = referrerPlace.uri;
|
||||
|
||||
do_check_false(gGlobalHistory.isVisited(place.uri));
|
||||
gHistory.updatePlaces(place, function(aResultCode, aPlaceInfo) {
|
||||
do_check_true(Components.isSuccessCode(aResultCode));
|
||||
gHistory.updatePlaces(place, expectHandleResult(function(aPlaceInfo) {
|
||||
do_check_true(gGlobalHistory.isVisited(place.uri));
|
||||
|
||||
do_check_eq(aPlaceInfo.visits[0].sessionId, sessionId);
|
||||
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
// test with empty mozIVisitInfoCallback object
|
||||
function test_callbacks_not_supplied()
|
||||
{
|
||||
const URLS = [
|
||||
"imap://cyrus.andrew.cmu.edu/archive.imap", // bad URI
|
||||
"http://mozilla.org/" // valid URI
|
||||
];
|
||||
let places = [];
|
||||
URLS.forEach(function(url) {
|
||||
try {
|
||||
let place = {
|
||||
uri: NetUtil.newURI(url),
|
||||
title: "test for " + url,
|
||||
visits: [
|
||||
new VisitInfo(),
|
||||
],
|
||||
};
|
||||
places.push(place);
|
||||
}
|
||||
catch (e if e.result === Cr.NS_ERROR_FAILURE) {
|
||||
// NetUtil.newURI() can throw if e.g. our app knows about imap://
|
||||
// but the account is not set up and so the URL is invalid for us.
|
||||
// Note this in the log but ignore as it's not the subject of this test.
|
||||
do_log_info("Could not construct URI for '" + url + "'; ignoring");
|
||||
}
|
||||
});
|
||||
|
||||
gHistory.updatePlaces(places, {} );
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
Services.obs.removeObserver(observer, TOPIC_UPDATEPLACES_COMPLETE);
|
||||
waitForAsyncUpdates(run_next_test);
|
||||
},
|
||||
};
|
||||
Services.obs.addObserver(observer, TOPIC_UPDATEPLACES_COMPLETE, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1290,6 +1345,7 @@ function test_referrer_sessionId_persists()
|
||||
test_title_change_notifies,
|
||||
test_visit_notifies,
|
||||
test_referrer_sessionId_persists,
|
||||
test_callbacks_not_supplied,
|
||||
].forEach(add_test);
|
||||
|
||||
function run_test()
|
||||
|
@ -58,7 +58,6 @@ FORCE_USE_PIC = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
include $(topsrcdir)/config/config.mk
|
||||
# need this to suppress errors when compiling common/linux/eintr_wrapper.h
|
||||
OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
|
||||
endif
|
||||
|
@ -342,7 +342,7 @@ nsGtkIMModule::OnFocusWindow(nsWindow* aWindow)
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): OnFocusWindow, aWindow=%p, mLastFocusedWindow=%p",
|
||||
this, aWindow));
|
||||
this, aWindow, mLastFocusedWindow));
|
||||
mLastFocusedWindow = aWindow;
|
||||
Focus();
|
||||
}
|
||||
@ -550,7 +550,8 @@ nsGtkIMModule::SetInputMode(nsWindow* aCaller, const IMEContext* aContext)
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): SetInputMode, aCaller=%p, aState=%s mHTMLInputType=%s",
|
||||
this, aCaller, GetEnabledStateName(aContext->mStatus), aContext->mHTMLInputType.get()));
|
||||
this, aCaller, GetEnabledStateName(aContext->mStatus),
|
||||
NS_ConvertUTF16toUTF8(aContext->mHTMLInputType).get()));
|
||||
|
||||
if (aCaller != mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
@ -726,8 +727,7 @@ nsGtkIMModule::Focus()
|
||||
GtkIMContext *im = GetContext();
|
||||
if (!im) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, there are no context",
|
||||
this));
|
||||
(" FAILED, there are no context"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1119,7 +1119,7 @@ nsGtkIMModule::DispatchCompositionStart()
|
||||
}
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" mCompositionStart=%lu", mCompositionStart));
|
||||
(" mCompositionStart=%u", mCompositionStart));
|
||||
mIsComposing = PR_TRUE;
|
||||
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_START,
|
||||
mLastFocusedWindow);
|
||||
@ -1329,7 +1329,7 @@ nsGtkIMModule::SetTextRangeList(nsTArray<nsTextRange> &aTextRangeList)
|
||||
aTextRangeList.AppendElement(range);
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" mStartOffset=%lu, mEndOffset=%lu, mRangeType=%s",
|
||||
(" mStartOffset=%u, mEndOffset=%u, mRangeType=%s",
|
||||
range.mStartOffset, range.mEndOffset,
|
||||
GetRangeTypeName(range.mRangeType)));
|
||||
} while (pango_attr_iterator_next(iter));
|
||||
@ -1347,7 +1347,7 @@ nsGtkIMModule::SetTextRangeList(nsTArray<nsTextRange> &aTextRangeList)
|
||||
aTextRangeList.AppendElement(range);
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" mStartOffset=%lu, mEndOffset=%lu, mRangeType=%s",
|
||||
(" mStartOffset=%u, mEndOffset=%u, mRangeType=%s",
|
||||
range.mStartOffset, range.mEndOffset,
|
||||
GetRangeTypeName(range.mRangeType)));
|
||||
|
||||
@ -1360,7 +1360,7 @@ void
|
||||
nsGtkIMModule::SetCursorPosition(PRUint32 aTargetOffset)
|
||||
{
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): SetCursorPosition, aTargetOffset=%lu",
|
||||
("GtkIMModule(%p): SetCursorPosition, aTargetOffset=%u",
|
||||
this, aTargetOffset));
|
||||
|
||||
if (aTargetOffset == PR_UINT32_MAX) {
|
||||
|
@ -55,10 +55,6 @@ EXPORT_LIBRARY = 1
|
||||
GRE_MODULE = 1
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
|
||||
CSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCPPSRCS) \
|
||||
$(XPCOM_GLUENS_SRC_LCPPSRCS) \
|
||||
@ -128,7 +124,7 @@ EXPORTS_mozilla = \
|
||||
# Force use of PIC
|
||||
FORCE_USE_PIC = 1
|
||||
|
||||
GARBAGE += $(XPCOM_GLUE_SRC_LCSRCS) $(XPCOM_GLUE_SRC_LCPPSRCS) $(XPCOM_GLUENS_SRC_LCPPSRCS) $(wildcard *.$(OBJ_SUFFIX))
|
||||
GARBAGE += $(XPCOM_GLUE_SRC_LCPPSRCS) $(XPCOM_GLUENS_SRC_LCPPSRCS) $(wildcard *.$(OBJ_SUFFIX))
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
@ -148,5 +144,5 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
endif
|
||||
|
||||
export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS)
|
||||
export:: $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS)
|
||||
$(INSTALL) $^ .
|
||||
|
@ -55,10 +55,6 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../build \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCPPSRCS) \
|
||||
$(XPCOM_GLUENS_SRC_LCPPSRCS) \
|
||||
|
@ -54,10 +54,6 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../build \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCPPSRCS) \
|
||||
$(XPCOM_GLUENS_SRC_LCPPSRCS) \
|
||||
@ -69,7 +65,7 @@ SDK_LIBRARY = \
|
||||
$(LIB_PREFIX)xpcomglue_s_nomozalloc.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
GARBAGE += $(CSRCS) $(CPPSRCS) DeadlockDetector.h SSE.h arm.h
|
||||
GARBAGE += $(CPPSRCS) DeadlockDetector.h SSE.h arm.h
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
@ -94,7 +90,7 @@ OS_COMPILE_CFLAGS += -Zl
|
||||
DEFINES += -D_USE_ANSI_CPP
|
||||
endif
|
||||
|
||||
export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS) $(topsrcdir)/xpcom/glue/nsStringAPI.cpp $(topsrcdir)/xpcom/glue/GenericModule.cpp $(topsrcdir)/xpcom/glue/DeadlockDetector.h $(topsrcdir)/xpcom/glue/SSE.h $(topsrcdir)/xpcom/glue/arm.h
|
||||
export:: $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS) $(topsrcdir)/xpcom/glue/nsStringAPI.cpp $(topsrcdir)/xpcom/glue/GenericModule.cpp $(topsrcdir)/xpcom/glue/DeadlockDetector.h $(topsrcdir)/xpcom/glue/SSE.h $(topsrcdir)/xpcom/glue/arm.h
|
||||
$(INSTALL) $^ .
|
||||
|
||||
ifdef TARGET_XPCOM_ABI
|
||||
|
@ -34,12 +34,6 @@
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
XPCOM_GLUE_SRC_LCSRCS = \
|
||||
pldhash.c \
|
||||
$(NULL)
|
||||
|
||||
XPCOM_GLUE_SRC_CSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCSRCS))
|
||||
|
||||
XPCOM_GLUE_SRC_LCPPSRCS = \
|
||||
nsArrayEnumerator.cpp \
|
||||
nsArrayUtils.cpp \
|
||||
@ -66,6 +60,7 @@ XPCOM_GLUE_SRC_LCPPSRCS = \
|
||||
nsCycleCollectionParticipant.cpp \
|
||||
nsCycleCollectorUtils.cpp \
|
||||
nsDeque.cpp \
|
||||
pldhash.cpp \
|
||||
$(NULL)
|
||||
|
||||
XPCOM_GLUE_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCPPSRCS))
|
||||
|
@ -71,10 +71,6 @@ LINKSRC = nsGlueLinkingNull.cpp
|
||||
$(warning TinderboxPrint:<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=298044">Error: XPCOM Glue</a>)
|
||||
endif
|
||||
|
||||
CSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
$(XPCOM_GLUE_SRC_LCPPSRCS) \
|
||||
nsStringAPI.cpp \
|
||||
@ -104,7 +100,7 @@ USE_STATIC_LIBS = 1
|
||||
# Don't use STL wrappers here (i.e. wrapped <new>); they require mozalloc
|
||||
STL_FLAGS =
|
||||
|
||||
GARBAGE += $(XPCOM_GLUE_SRC_LCSRCS) $(XPCOM_GLUE_SRC_LCPPSRCS) $(wildcard *.$(OBJ_SUFFIX))
|
||||
GARBAGE += $(XPCOM_GLUE_SRC_LCPPSRCS) $(wildcard *.$(OBJ_SUFFIX))
|
||||
|
||||
SRCS_IN_OBJDIR = 1
|
||||
|
||||
@ -117,7 +113,7 @@ OS_COMPILE_CFLAGS += -Zl
|
||||
DEFINES += -D_USE_ANSI_CPP
|
||||
endif
|
||||
|
||||
export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) $(topsrcdir)/xpcom/glue/nsStringAPI.cpp
|
||||
export:: $(XPCOM_GLUE_SRC_CPPSRCS) $(topsrcdir)/xpcom/glue/nsStringAPI.cpp
|
||||
$(INSTALL) $^ .
|
||||
|
||||
GARBAGE += nsStringAPI.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user