Merge last green changeset from mozilla-inbound to mozilla-central

This commit is contained in:
Marco Bonardo 2011-10-13 15:48:46 +02:00
Родитель 534f94fed2 3e721e1e4d
Коммит b478778440
124 изменённых файлов: 1994 добавлений и 809 удалений

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

@ -908,17 +908,9 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
// or the start of a new line. Getting text at the line should provide the line with the visual caret,
// otherwise screen readers will announce the wrong line as the user presses up or down arrow and land
// at the end of a line.
nsCOMPtr<nsISelection> domSel;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryInterface(domSel));
nsRefPtr<nsFrameSelection> frameSelection;
rv = privateSelection->GetFrameSelection(getter_AddRefs(frameSelection));
NS_ENSURE_SUCCESS(rv, rv);
if (frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
if (frameSelection &&
frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
-- aOffset; // We are at the start of a line
}
}
@ -1587,12 +1579,14 @@ nsHyperTextAccessible::SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos)
// If range 0 was successfully set, clear any additional selection
// ranges remaining from previous selection
nsCOMPtr<nsISelection> domSel;
nsCOMPtr<nsISelectionController> selCon;
GetSelections(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selCon), getter_AddRefs(domSel));
if (domSel) {
PRInt32 numRanges;
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
NS_ENSURE_STATE(frameSelection);
nsCOMPtr<nsISelection> domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
NS_ENSURE_STATE(domSel);
PRInt32 numRanges = 0;
domSel->GetRangeCount(&numRanges);
for (PRInt32 count = 0; count < numRanges - 1; count ++) {
@ -1600,16 +1594,12 @@ nsHyperTextAccessible::SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos)
domSel->GetRangeAt(1, getter_AddRefs(range));
domSel->RemoveRange(range);
}
}
if (selCon) {
// XXX I'm not sure this can do synchronous scrolling. If the last param is
// set to true, this calling might flush the pending reflow. See bug 418470.
selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION, 0);
}
return NS_OK;
return frameSelection->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION,
0);
}
NS_IMETHODIMP
@ -1635,13 +1625,15 @@ nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
// Turn the focus node and offset of the selection into caret hypretext
// offset.
nsCOMPtr<nsISelection> domSel;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
NS_ENSURE_STATE(frameSelection);
nsISelection* domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
NS_ENSURE_STATE(domSel);
nsCOMPtr<nsIDOMNode> focusDOMNode;
rv = domSel->GetFocusNode(getter_AddRefs(focusDOMNode));
nsresult rv = domSel->GetFocusNode(getter_AddRefs(focusDOMNode));
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 focusOffset;
@ -1665,18 +1657,19 @@ nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
return NS_OK;
}
PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
PRInt32
nsHyperTextAccessible::GetCaretLineNumber()
{
// Provide the line number for the caret, relative to the
// currently focused node. Use a 1-based index
nsCOMPtr<nsISelection> domSel;
GetSelections(nsISelectionController::SELECTION_NORMAL, nsnull,
getter_AddRefs(domSel));
nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryInterface(domSel));
NS_ENSURE_TRUE(privateSelection, -1);
nsRefPtr<nsFrameSelection> frameSelection;
privateSelection->GetFrameSelection(getter_AddRefs(frameSelection));
NS_ENSURE_TRUE(frameSelection, -1);
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
if (!frameSelection)
return -1;
nsISelection* domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
if (!domSel)
return - 1;
nsCOMPtr<nsIDOMNode> caretNode;
domSel->GetFocusNode(getter_AddRefs(caretNode));
@ -1731,81 +1724,50 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
return lineNumber;
}
nsresult
nsHyperTextAccessible::GetSelections(PRInt16 aType,
nsISelectionController **aSelCon,
nsISelection **aDomSel,
already_AddRefed<nsFrameSelection>
nsHyperTextAccessible::FrameSelection()
{
nsIFrame* frame = GetFrame();
return frame->GetFrameSelection();
}
void
nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
nsCOMArray<nsIDOMRange>* aRanges)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
if (!frameSelection)
return;
if (aSelCon) {
*aSelCon = nsnull;
}
if (aDomSel) {
*aDomSel = nsnull;
}
if (aRanges) {
aRanges->Clear();
}
nsISelection* domSel = frameSelection->GetSelection(aType);
if (!domSel)
return;
nsCOMPtr<nsISelection> domSel;
nsCOMPtr<nsISelectionController> selCon;
nsCOMPtr<nsINode> startNode = GetNode();
nsCOMPtr<nsIEditor> editor;
GetAssociatedEditor(getter_AddRefs(editor));
nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
if (peditor) {
// Case 1: plain text editor
// This is for form controls which have their own
// selection controller separate from the document, for example
// HTML:input, HTML:textarea, XUL:textbox, etc.
editor->GetSelectionController(getter_AddRefs(selCon));
}
else {
// Case 2: rich content subtree (can be rich editor)
// This uses the selection controller from the entire document
nsIFrame *frame = GetFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
// Get the selection and selection controller
frame->GetSelectionController(GetPresContext(),
getter_AddRefs(selCon));
}
NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
selCon->GetSelection(aType, getter_AddRefs(domSel));
NS_ENSURE_TRUE(domSel, NS_ERROR_FAILURE);
if (aSelCon) {
NS_ADDREF(*aSelCon = selCon);
}
if (aDomSel) {
NS_ADDREF(*aDomSel = domSel);
}
if (aRanges) {
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(domSel));
nsCOMPtr<nsINode> startNode = GetNode();
if (peditor) {
if (editor) {
nsCOMPtr<nsIDOMElement> editorRoot;
editor->GetRootElement(getter_AddRefs(editorRoot));
startNode = do_QueryInterface(editorRoot);
}
NS_ENSURE_STATE(startNode);
if (!startNode)
return;
PRUint32 childCount = startNode->GetChildCount();
nsCOMPtr<nsIDOMNode> startDOMNode(do_QueryInterface(startNode));
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(domSel));
nsresult rv = privSel->
GetRangesForIntervalCOMArray(startDOMNode, 0, startDOMNode, childCount,
PR_TRUE, aRanges);
NS_ENSURE_SUCCESS(rv, rv);
true, aRanges);
NS_ENSURE_SUCCESS(rv,);
// Remove collapsed ranges
PRInt32 numRanges = aRanges->Count();
for (PRInt32 count = 0; count < numRanges; count ++) {
bool isCollapsed;
bool isCollapsed = false;
(*aRanges)[count]->GetCollapsed(&isCollapsed);
if (isCollapsed) {
aRanges->RemoveObjectAt(count);
@ -1815,20 +1777,17 @@ nsHyperTextAccessible::GetSelections(PRInt16 aType,
}
}
return NS_OK;
}
/*
* Gets the number of selected regions.
*/
NS_IMETHODIMP nsHyperTextAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
NS_IMETHODIMP
nsHyperTextAccessible::GetSelectionCount(PRInt32* aSelectionCount)
{
nsCOMPtr<nsISelection> domSel;
nsCOMArray<nsIDOMRange> ranges;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, nsnull, &ranges);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_ARG_POINTER(aSelectionCount);
*aSelectionCount = 0;
nsCOMArray<nsIDOMRange> ranges;
GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
*aSelectionCount = ranges.Count();
return NS_OK;
@ -1837,15 +1796,17 @@ NS_IMETHODIMP nsHyperTextAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
/*
* Gets the start and end offset of the specified selection.
*/
NS_IMETHODIMP nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum, PRInt32 *aStartOffset, PRInt32 *aEndOffset)
NS_IMETHODIMP
nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum,
PRInt32* aStartOffset,
PRInt32* aEndOffset)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
*aStartOffset = *aEndOffset = 0;
nsCOMPtr<nsISelection> domSel;
nsCOMArray<nsIDOMRange> ranges;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel), &ranges);
NS_ENSURE_SUCCESS(rv, rv);
GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
PRInt32 rangeCount = ranges.Count();
if (aSelectionNum < 0 || aSelectionNum >= rangeCount)
@ -1857,18 +1818,19 @@ NS_IMETHODIMP nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum, P
nsCOMPtr<nsIDOMNode> startDOMNode;
range->GetStartContainer(getter_AddRefs(startDOMNode));
nsCOMPtr<nsINode> startNode(do_QueryInterface(startDOMNode));
PRInt32 startOffset;
PRInt32 startOffset = 0;
range->GetStartOffset(&startOffset);
// Get end point
nsCOMPtr<nsIDOMNode> endDOMNode;
range->GetEndContainer(getter_AddRefs(endDOMNode));
nsCOMPtr<nsINode> endNode(do_QueryInterface(endDOMNode));
PRInt32 endOffset;
PRInt32 endOffset = 0;
range->GetEndOffset(&endOffset);
PRInt16 rangeCompareResult;
rv = range->CompareBoundaryPoints(nsIDOMRange::START_TO_END, range, &rangeCompareResult);
PRInt16 rangeCompareResult = 0;
nsresult rv = range->CompareBoundaryPoints(nsIDOMRange::START_TO_END, range,
&rangeCompareResult);
NS_ENSURE_SUCCESS(rv, rv);
if (rangeCompareResult < 0) {
@ -1898,15 +1860,17 @@ nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum,
PRInt32 aStartOffset,
PRInt32 aEndOffset)
{
nsCOMPtr<nsISelection> domSel;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
NS_ENSURE_STATE(frameSelection);
nsCOMPtr<nsISelection> domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
NS_ENSURE_STATE(domSel);
// Caret is a collapsed selection
bool isOnlyCaret = (aStartOffset == aEndOffset);
PRInt32 rangeCount;
PRInt32 rangeCount = 0;
domSel->GetRangeCount(&rangeCount);
nsCOMPtr<nsIDOMRange> range;
if (aSelectionNum == rangeCount) { // Add a range
@ -1921,10 +1885,10 @@ nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum,
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
}
PRInt32 startOffset, endOffset;
PRInt32 startOffset = 0, endOffset = 0;
nsCOMPtr<nsIDOMNode> startNode, endNode;
rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset,
nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset,
getter_AddRefs(startNode), &startOffset,
getter_AddRefs(endNode), &endOffset);
NS_ENSURE_SUCCESS(rv, rv);
@ -1936,23 +1900,30 @@ nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum,
range->SetEnd(endNode, endOffset);
NS_ENSURE_SUCCESS(rv, rv);
if (aSelectionNum == rangeCount) { // Add successfully created new range
// If new range was created then add it, otherwise notify selection listeners
// that existing selection range was changed.
if (aSelectionNum == rangeCount)
return domSel->AddRange(range);
}
domSel->RemoveRange(range);
domSel->AddRange(range);
return NS_OK;
}
/*
* Adds a selection bounded by the specified offsets.
*/
NS_IMETHODIMP nsHyperTextAccessible::AddSelection(PRInt32 aStartOffset, PRInt32 aEndOffset)
NS_IMETHODIMP
nsHyperTextAccessible::AddSelection(PRInt32 aStartOffset, PRInt32 aEndOffset)
{
nsCOMPtr<nsISelection> domSel;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
NS_ENSURE_STATE(frameSelection);
PRInt32 rangeCount;
nsCOMPtr<nsISelection> domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
NS_ENSURE_STATE(domSel);
PRInt32 rangeCount = 0;
domSel->GetRangeCount(&rangeCount);
return SetSelectionBounds(rangeCount, aStartOffset, aEndOffset);
@ -1961,12 +1932,15 @@ NS_IMETHODIMP nsHyperTextAccessible::AddSelection(PRInt32 aStartOffset, PRInt32
/*
* Removes the specified selection.
*/
NS_IMETHODIMP nsHyperTextAccessible::RemoveSelection(PRInt32 aSelectionNum)
NS_IMETHODIMP
nsHyperTextAccessible::RemoveSelection(PRInt32 aSelectionNum)
{
nsCOMPtr<nsISelection> domSel;
nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
nsnull, getter_AddRefs(domSel));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
NS_ENSURE_STATE(frameSelection);
nsCOMPtr<nsISelection> domSel =
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
NS_ENSURE_STATE(domSel);
PRInt32 rangeCount;
domSel->GetRangeCount(&rangeCount);
@ -2348,9 +2322,7 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes)
{
nsCOMArray<nsIDOMRange> ranges;
nsresult rv = GetSelections(nsISelectionController::SELECTION_SPELLCHECK,
nsnull, nsnull, &ranges);
NS_ENSURE_SUCCESS(rv, rv);
GetSelectionDOMRanges(nsISelectionController::SELECTION_SPELLCHECK, &ranges);
PRInt32 rangeCount = ranges.Count();
if (!rangeCount)
@ -2362,7 +2334,7 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
NS_ENSURE_STATE(nsrange);
PRInt16 result;
rv = nsrange->ComparePoint(aNode, aNodeOffset, &result);
nsresult rv = nsrange->ComparePoint(aNode, aNodeOffset, &result);
NS_ENSURE_SUCCESS(rv, rv);
// ComparePoint checks boundary points, but we need to check that
// text at aNodeOffset is inside the range.
@ -2381,7 +2353,7 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
if (result == 1) { // range is before point
PRInt32 startHTOffset = 0;
rv = DOMRangeBoundToHypertextOffset(range, PR_FALSE, PR_TRUE,
nsresult rv = DOMRangeBoundToHypertextOffset(range, PR_FALSE, PR_TRUE,
&startHTOffset);
NS_ENSURE_SUCCESS(rv, rv);
@ -2390,7 +2362,7 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
} else if (result == -1) { // range is after point
PRInt32 endHTOffset = 0;
rv = DOMRangeBoundToHypertextOffset(range, PR_TRUE, PR_FALSE,
nsresult rv = DOMRangeBoundToHypertextOffset(range, PR_TRUE, PR_FALSE,
&endHTOffset);
NS_ENSURE_SUCCESS(rv, rv);
@ -2399,7 +2371,7 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
} else { // point is in range
PRInt32 startHTOffset = 0;
rv = DOMRangeBoundToHypertextOffset(range, PR_TRUE, PR_TRUE,
nsresult rv = DOMRangeBoundToHypertextOffset(range, PR_TRUE, PR_TRUE,
&startHTOffset);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -352,21 +352,14 @@ protected:
// Selection helpers
/**
* Get the relevant selection interfaces and ranges for the current hyper
* text.
*
* @param aType [in] the selection type
* @param aSelCon [out, optional] the selection controller for the current
* hyper text
* @param aDomSel [out, optional] the selection interface for the current
* hyper text
* @param aRanges [out, optional] the selected ranges within the current
* subtree
* Return frame selection object for the accessible.
*/
nsresult GetSelections(PRInt16 aType,
nsISelectionController **aSelCon,
nsISelection **aDomSel = nsnull,
nsCOMArray<nsIDOMRange>* aRanges = nsnull);
virtual already_AddRefed<nsFrameSelection> FrameSelection();
/**
* Return selection ranges within the accessible subtree.
*/
void GetSelectionDOMRanges(PRInt16 aType, nsCOMArray<nsIDOMRange>* aRanges);
nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);

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

@ -882,6 +882,17 @@ nsXULTextFieldAccessible::CacheChildren()
while ((child = walker.NextChild()) && AppendChild(child));
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTextFieldAccessible: nsHyperTextAccessible protected
already_AddRefed<nsFrameSelection>
nsXULTextFieldAccessible::FrameSelection()
{
nsCOMPtr<nsIContent> inputContent(GetInputField());
nsIFrame* frame = inputContent->GetPrimaryFrame();
return frame->GetFrameSelection();
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTextFieldAccessible protected

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

@ -276,6 +276,9 @@ protected:
// nsAccessible
virtual void CacheChildren();
// nsHyperTextAccessible
virtual already_AddRefed<nsFrameSelection> FrameSelection();
// nsXULTextFieldAccessible
already_AddRefed<nsIContent> GetInputField() const;
};

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

@ -56,6 +56,7 @@ DIRS = \
states \
table \
text \
textselection \
tree \
treeupdate \
value \

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

@ -23,6 +23,7 @@ const EVENT_TEXT_ATTRIBUTE_CHANGED = nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHA
const EVENT_TEXT_CARET_MOVED = nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED;
const EVENT_TEXT_INSERTED = nsIAccessibleEvent.EVENT_TEXT_INSERTED;
const EVENT_TEXT_REMOVED = nsIAccessibleEvent.EVENT_TEXT_REMOVED;
const EVENT_TEXT_SELECTION_CHANGED = nsIAccessibleEvent.EVENT_TEXT_SELECTION_CHANGED;
const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE;
////////////////////////////////////////////////////////////////////////////////

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

@ -0,0 +1,53 @@
#
# ***** 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/textselection
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_general.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)

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

@ -0,0 +1,170 @@
<html>
<head>
<title>Text selection testing</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<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="../events.js"></script>
<script type="application/javascript">
/**
* Invokers
*/
function addSelection(aID, aStartOffset, aEndOffset)
{
this.hyperTextNode = getNode(aID);
this.hyperText = getAccessible(aID, [ nsIAccessibleText ]);
this.eventSeq = [
new invokerChecker(EVENT_TEXT_SELECTION_CHANGED, aID)
];
this.invoke = function addSelection_invoke()
{
this.hyperText.addSelection(aStartOffset, aEndOffset);
}
this.finalCheck = function addSelection_finalCheck()
{
is(this.hyperText.selectionCount, 1,
"addSelection: Wrong selection count for " + aID);
var startOffset = {}, endOffset = {};
this.hyperText.getSelectionBounds(0, startOffset, endOffset);
is(startOffset.value, aStartOffset,
"addSelection: Wrong start offset for " + aID);
is(endOffset.value, aEndOffset,
"addSelection: Wrong end offset for " + aID);
}
this.getID = function addSelection_getID()
{
return "nsIAccessibleText::addSelection test for " + aID;
}
}
function changeSelection(aID, aStartOffset, aEndOffset)
{
this.hyperTextNode = getNode(aID);
this.hyperText = getAccessible(aID, [ nsIAccessibleText ]);
this.eventSeq = [
new invokerChecker(EVENT_TEXT_SELECTION_CHANGED, aID)
];
this.invoke = function changeSelection_invoke()
{
this.hyperText.setSelectionBounds(0, aStartOffset, aEndOffset);
}
this.finalCheck = function changeSelection_finalCheck()
{
is(this.hyperText.selectionCount, 1,
"setSelectionBounds: Wrong selection count for " + aID);
var startOffset = {}, endOffset = {};
this.hyperText.getSelectionBounds(0, startOffset, endOffset);
is(startOffset.value, aStartOffset,
"setSelectionBounds: Wrong start offset for " + aID);
is(endOffset.value, aEndOffset,
"setSelectionBounds: Wrong end offset for " + aID);
}
this.getID = function changeSelection_getID()
{
return "nsIAccessibleText::setSelectionBounds test for " + aID;
}
}
function removeSelection(aID)
{
this.hyperText = getAccessible(aID, [ nsIAccessibleText ]);
this.eventSeq = [
new invokerChecker(EVENT_TEXT_SELECTION_CHANGED, aID)
];
this.invoke = function removeSelection_invoke()
{
this.hyperText.removeSelection(0);
}
this.finalCheck = function removeSelection_finalCheck()
{
is(this.hyperText.selectionCount, 0,
"removeSelection: Wrong selection count for " + aID);
}
this.getID = function removeSelection_getID()
{
return "nsIAccessibleText::removeSelection test for " + aID;
}
}
function onfocusEventSeq(aID)
{
var caretMovedChecker =
new invokerChecker(EVENT_TEXT_CARET_MOVED, aID);
var selChangedChecker =
new invokerChecker(EVENT_TEXT_SELECTION_CHANGED, aID);
selChangedChecker.unexpected = true;
return [ caretMovedChecker, selChangedChecker ];
}
/**
* Do tests
*/
//gA11yEventDumpToConsole = true; // debug stuff
var gQueue = null;
function doTests()
{
gQueue = new eventQueue();
gQueue.push(new addSelection("paragraph", 1, 3));
gQueue.push(new changeSelection("paragraph", 2, 4));
//gQueue.push(new removeSelection("paragraph"));
todo(false, "removeSelection doesn't fire text selection changed events, see bug bug 688124.");
gQueue.push(new synthFocus("textbox", onfocusEventSeq("textbox")));
gQueue.push(new changeSelection("textbox", 1, 3));
gQueue.push(new synthFocus("textarea", onfocusEventSeq("textarea")));
gQueue.push(new changeSelection("textarea", 1, 3));
gQueue.invoke(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=688126"
title="nsIAccessibleText::setSelectionBounds doesn't fire text selection changed events in some cases">
Mozilla Bug 688126
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<p id="paragraph">hello</p>
<input id="textbox" value="hello"/>
<textarea id="textarea">hello</textarea>
</body>
</html>

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

@ -362,11 +362,6 @@ LIBS_DESC_SUFFIX = @LIBS_DESC_SUFFIX@
USE_N32 = @USE_N32@
HAVE_64BIT_OS = @HAVE_64BIT_OS@
# Temp hack. It is not my intention to leave this crap in here for ever.
# Im talking to fur right now to solve the problem without introducing
# NS_USE_NATIVE to the build system -ramiro.
NS_USE_NATIVE = @NS_USE_NATIVE@
CC = @CC@
CXX = @CXX@

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

@ -2488,7 +2488,6 @@ ia64*-hpux*)
if test "$SOLARIS_SUNPRO_CC"; then
LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN:\$\$ORIGIN/..' -z lazyload -z combreloc -z muldefs"
LIBS="-lCrun -lCstd -lc $LIBS"
NS_USE_NATIVE=1
AC_DEFINE(NSCAP_DISABLE_DEBUG_PTR_TYPES)
CFLAGS="$CFLAGS -xlibmieee -xstrconst -xbuiltin=%all -D__FUNCTION__=__func__"
CXXFLAGS="$CXXFLAGS -xlibmieee -xbuiltin=%all -features=tmplife,tmplrefstatic,extensions -norunpath -D__FUNCTION__=__func__ -template=no%extdef"
@ -8209,7 +8208,6 @@ AC_SUBST(WINDRES)
AC_SUBST(IMPLIB)
AC_SUBST(FILTER)
AC_SUBST(BIN_FLAGS)
AC_SUBST(NS_USE_NATIVE)
AC_SUBST(MOZ_WIDGET_TOOLKIT)
AC_SUBST(MOZ_UPDATE_XTERM)
AC_SUBST(MOZ_PLATFORM_MAEMO)

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

@ -1099,8 +1099,18 @@ nsExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI,
nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, rv);
// Allow data URIs (let them skip the CheckMayLoad call), since we want
// to allow external resources from data URIs regardless of the difference
// in URI scheme.
bool doesInheritSecurityContext;
rv =
NS_URIChainHasFlags(aURI,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&doesInheritSecurityContext);
if (NS_FAILED(rv) || !doesInheritSecurityContext) {
rv = requestingPrincipal->CheckMayLoad(aURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OTHER,

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

@ -105,6 +105,10 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
#ifdef ANDROID
#include "nsXULAppAPI.h"
#endif
class nsAsyncInstantiateEvent : public nsRunnable {
public:
// This stores both the content and the frame so that Instantiate calls can be
@ -200,6 +204,9 @@ nsPluginErrorEvent::Run()
mContent.get()));
nsString type;
switch (mState) {
case ePluginClickToPlay:
type = NS_LITERAL_STRING("PluginClickToPlay");
break;
case ePluginUnsupported:
type = NS_LITERAL_STRING("PluginNotFound");
break;
@ -1056,6 +1063,10 @@ nsObjectLoadingContent::ObjectState() const
case eType_Image:
return ImageState();
case eType_Plugin:
#ifdef ANDROID
if (XRE_GetProcessType() == GeckoProcessType_Content)
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
#endif
case eType_Document:
// These are OK. If documents start to load successfully, they display
// something, and are thus not broken in this sense. The same goes for
@ -1070,6 +1081,8 @@ nsObjectLoadingContent::ObjectState() const
// Otherwise, broken
nsEventStates state = NS_EVENT_STATE_BROKEN;
switch (mFallbackReason) {
case ePluginClickToPlay:
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
case ePluginDisabled:
state |= NS_EVENT_STATE_HANDLER_DISABLED;
break;
@ -1949,6 +1962,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
/* static */ PluginSupportState
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
{
#ifdef ANDROID
if (XRE_GetProcessType() == GeckoProcessType_Content)
return ePluginClickToPlay;
#endif
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if (!pluginHost) {

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

@ -65,7 +65,8 @@ enum PluginSupportState {
ePluginBlocklisted, // The plugin is blocklisted and disabled
ePluginOutdated, // The plugin is considered outdated, but not disabled
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
ePluginCrashed
ePluginCrashed,
ePluginClickToPlay
};
/**

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

@ -357,7 +357,7 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
DoSetRange(newStartNode, newStartOffset, newEndNode, newEndOffset,
newRoot ? newRoot : mRoot.get()
#ifdef DEBUG
, !newEndNode->GetParent()
, !newEndNode->GetParent() || !newStartNode->GetParent()
#endif
);
}

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

@ -3066,6 +3066,8 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP
Point baselineOrigin =
Point(point.x * devUnitsPerAppUnit, point.y * devUnitsPerAppUnit);
float advanceSum = 0;
for (PRUint32 c = 0; c < numRuns; c++) {
gfxFont *font = runs[c].mFont;
PRUint32 endRun = 0;
@ -3084,8 +3086,6 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP
std::vector<Glyph> glyphBuf;
float advanceSum = 0;
for (PRUint32 i = runs[c].mCharacterOffset; i < endRun; i++) {
Glyph newGlyph;
if (glyphs[i].IsSimpleGlyph()) {

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

@ -264,6 +264,8 @@ private:
// Content is the full screen element, or a frame containing the
// current full-screen element.
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(34)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
/**
* NOTE: do not go over 63 without updating nsEventStates::InternalType!

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

@ -4888,14 +4888,7 @@ nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
NS_ASSERTION(sgo, "nativeObj not a global object!");
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
if (win->IsOuterWindow()) {
if (!win->EnsureInnerWindow()) {
return NS_ERROR_FAILURE;
}
*parentObj = win->GetCurrentInnerWindowInternal()->FastGetGlobalJSObject();
return NS_OK;
}
NS_ASSERTION(win->IsInnerWindow(), "Should be inner window.");
JSObject *winObj = win->FastGetGlobalJSObject();
if (!winObj) {

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

@ -299,6 +299,16 @@ public:
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsWrapperCache
JSObject *WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
NS_ASSERTION(IsOuterWindow(),
"Inner window supports nsWrapperCache, fix WrapObject!");
*triedToWrap = true;
return EnsureInnerWindow() ? GetWrapper() : nsnull;
}
// nsIScriptGlobalObject
virtual nsIScriptContext *GetContext();
virtual JSObject *GetGlobalJSObject();

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

@ -94,6 +94,7 @@
#include "nsXPCOMCID.h"
#include "nsISupportsPrimitives.h"
#include "nsXULAppAPI.h"
#include "nsIXULRuntime.h"
// for the dialog
@ -2251,6 +2252,11 @@ nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
nsresult nsPluginHost::LoadPlugins()
{
#ifdef ANDROID
if (XRE_GetProcessType() == GeckoProcessType_Content) {
return NS_OK;
}
#endif
// do not do anything if it is already done
// use ReloadPlugins() to enforce loading
if (mPluginsLoaded)

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

@ -326,7 +326,7 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data,
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
}
pixman_image = pixman_image_create_bits (pixman_format, width ? width : 1, height ? height : 1,
pixman_image = pixman_image_create_bits (pixman_format, width, height,
(uint32_t *) data, stride ? stride : 4);
if (unlikely (pixman_image == NULL))

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

@ -201,9 +201,17 @@ ContainerLayerD3D10::RenderLayer()
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.SampleDesc.Count = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
device()->CreateTexture2D(&desc, NULL, getter_AddRefs(renderTexture));
HRESULT hr;
hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(renderTexture));
device()->CreateRenderTargetView(renderTexture, NULL, getter_AddRefs(rtView));
if (FAILED(hr)) {
LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create new texture for ContainerLayerD3D10!"),
hr);
return;
}
hr = device()->CreateRenderTargetView(renderTexture, NULL, getter_AddRefs(rtView));
NS_ASSERTION(SUCCEEDED(hr), "Failed to create render target view for ContainerLayerD3D10!");
effect()->GetVariableByName("vRenderTargetOffset")->
GetRawValue(previousRenderTargetOffset, 0, 8);

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

@ -0,0 +1,31 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_DIR_READER_FALLBACK_H_
#define BASE_DIR_READER_FALLBACK_H_
#pragma once
namespace base {
class DirReaderFallback {
public:
// Open a directory. If |IsValid| is true, then |Next| can be called to start
// the iteration at the beginning of the directory.
explicit DirReaderFallback(const char* directory_path) { }
// After construction, IsValid returns true iff the directory was
// successfully opened.
bool IsValid() const { return false; }
// Move to the next entry returning false if the iteration is complete.
bool Next() { return false; }
// Return the name of the current directory entry.
const char* name() { return 0;}
// Return the file descriptor which is being used.
int fd() const { return -1; }
// Returns true if this is a no-op fallback class (for testing).
static bool IsFallback() { return true; }
};
} // namespace base
#endif // BASE_DIR_READER_FALLBACK_H_

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

@ -0,0 +1,99 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_DIR_READER_LINUX_H_
#define BASE_DIR_READER_LINUX_H_
#pragma once
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "base/logging.h"
#include "base/eintr_wrapper.h"
// See the comments in dir_reader_posix.h about this.
namespace base {
struct linux_dirent {
uint64_t d_ino;
int64_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[0];
};
class DirReaderLinux {
public:
explicit DirReaderLinux(const char* directory_path)
: fd_(open(directory_path, O_RDONLY | O_DIRECTORY)),
offset_(0),
size_(0) {
memset(buf_, 0, sizeof(buf_));
}
~DirReaderLinux() {
if (fd_ >= 0) {
if (HANDLE_EINTR(close(fd_)))
DLOG(ERROR) << "Failed to close directory handle";
}
}
bool IsValid() const {
return fd_ >= 0;
}
// Move to the next entry returning false if the iteration is complete.
bool Next() {
if (size_) {
linux_dirent* dirent = reinterpret_cast<linux_dirent*>(&buf_[offset_]);
offset_ += dirent->d_reclen;
}
if (offset_ != size_)
return true;
const int r = syscall(__NR_getdents64, fd_, buf_, sizeof(buf_));
if (r == 0)
return false;
if (r == -1) {
DLOG(ERROR) << "getdents64 returned an error: " << errno;
return false;
}
size_ = r;
offset_ = 0;
return true;
}
const char* name() const {
if (!size_)
return NULL;
const linux_dirent* dirent =
reinterpret_cast<const linux_dirent*>(&buf_[offset_]);
return dirent->d_name;
}
int fd() const {
return fd_;
}
static bool IsFallback() {
return false;
}
private:
const int fd_;
unsigned char buf_[512];
size_t offset_, size_;
DISALLOW_COPY_AND_ASSIGN(DirReaderLinux);
};
} // namespace base
#endif // BASE_DIR_READER_LINUX_H_

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

@ -0,0 +1,37 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_DIR_READER_POSIX_H_
#define BASE_DIR_READER_POSIX_H_
#pragma once
#include "build/build_config.h"
// This header provides a class, DirReaderPosix, which allows one to open and
// read from directories without allocating memory. For the interface, see
// the generic fallback in dir_reader_fallback.h.
// Mac note: OS X has getdirentries, but it only works if we restrict Chrome to
// 32-bit inodes. There is a getdirentries64 syscall in 10.6, but it's not
// wrapped and the direct syscall interface is unstable. Using an unstable API
// seems worse than falling back to enumerating all file descriptors so we will
// probably never implement this on the Mac.
#if defined(OS_LINUX)
#include "base/dir_reader_linux.h"
#else
#include "base/dir_reader_fallback.h"
#endif
namespace base {
#if defined(OS_LINUX)
typedef DirReaderLinux DirReaderPosix;
#else
typedef DirReaderFallback DirReaderPosix;
#endif
} // namespace base
#endif // BASE_DIR_READER_POSIX_H_

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

@ -12,26 +12,36 @@
namespace base {
bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
InjectionDelegate* delegate) {
InjectiveMultimap m(m_in);
std::vector<int> extra_fds;
bool PerformInjectiveMultimapDestructive(
InjectiveMultimap* m, InjectionDelegate* delegate) {
static const size_t kMaxExtraFDs = 16;
int extra_fds[kMaxExtraFDs];
unsigned next_extra_fd = 0;
for (InjectiveMultimap::iterator i = m.begin(); i != m.end(); ++i) {
// DANGER: this function may not allocate.
for (InjectiveMultimap::iterator i = m->begin(); i != m->end(); ++i) {
int temp_fd = -1;
// We DCHECK the injectiveness of the mapping.
for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j)
DCHECK(i->dest != j->dest);
for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) {
DCHECK(i->dest != j->dest) << "Both fd " << i->source
<< " and " << j->source << " map to " << i->dest;
}
const bool is_identity = i->source == i->dest;
for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) {
for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) {
if (!is_identity && i->dest == j->source) {
if (temp_fd == -1) {
if (!delegate->Duplicate(&temp_fd, i->dest))
return false;
extra_fds.push_back(temp_fd);
if (next_extra_fd < kMaxExtraFDs) {
extra_fds[next_extra_fd++] = temp_fd;
} else {
DLOG(ERROR) << "PerformInjectiveMultimapDestructive overflowed "
<< "extra_fds. Leaking file descriptors!";
}
}
j->source = temp_fd;
@ -56,14 +66,18 @@ bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
delegate->Close(i->source);
}
for (std::vector<int>::const_iterator
i = extra_fds.begin(); i != extra_fds.end(); ++i) {
delegate->Close(*i);
}
for (unsigned i = 0; i < next_extra_fd; i++)
delegate->Close(extra_fds[i]);
return true;
}
bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
InjectionDelegate* delegate) {
InjectiveMultimap m(m_in);
return PerformInjectiveMultimapDestructive(&m, delegate);
}
bool FileDescriptorTableInjection::Duplicate(int* result, int fd) {
*result = HANDLE_EINTR(dup(fd));
return *result >= 0;

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

@ -65,10 +65,13 @@ typedef std::vector<InjectionArc> InjectiveMultimap;
bool PerformInjectiveMultimap(const InjectiveMultimap& map,
InjectionDelegate* delegate);
bool PerformInjectiveMultimapDestructive(InjectiveMultimap* map,
InjectionDelegate* delegate);
static inline bool ShuffleFileDescriptors(const InjectiveMultimap& map) {
// This function will not call malloc but will mutate |map|
static inline bool ShuffleFileDescriptors(InjectiveMultimap *map) {
FileDescriptorTableInjection delegate;
return PerformInjectiveMultimap(map, &delegate);
return PerformInjectiveMultimapDestructive(map, &delegate);
}
} // namespace base

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

@ -48,39 +48,34 @@ bool LaunchApp(const std::vector<std::string>& argv,
const environment_map& env_vars_to_set,
bool wait, ProcessHandle* process_handle,
ProcessArchitecture arch) {
#ifdef MOZ_MEMORY_ANDROID
/* We specifically don't call pthread_atfork in jemalloc because it is not
available in bionic until 2.3. However without it, jemalloc could
potentially deadlock, when stl allocates memory through jemalloc, after
fork and before execvp. Therefore, we must manually inform jemalloc here */
::_malloc_prefork();
#endif
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
// Illegal to allocate memory after fork and before execvp
InjectiveMultimap fd_shuffle1, fd_shuffle2;
fd_shuffle1.reserve(fds_to_remap.size());
fd_shuffle2.reserve(fds_to_remap.size());
pid_t pid = fork();
#ifdef MOZ_MEMORY_ANDROID
::_malloc_postfork();
#endif
if (pid < 0)
return false;
if (pid == 0) {
InjectiveMultimap fd_shuffle;
for (file_handle_mapping_vector::const_iterator
it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) {
fd_shuffle.push_back(InjectionArc(it->first, it->second, false));
fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
}
if (!ShuffleFileDescriptors(fd_shuffle))
exit(127);
if (!ShuffleFileDescriptors(&fd_shuffle1))
_exit(127);
CloseSuperfluousFds(fd_shuffle);
CloseSuperfluousFds(fd_shuffle2);
for (environment_map::const_iterator it = env_vars_to_set.begin();
it != env_vars_to_set.end(); ++it) {
if (setenv(it->first.c_str(), it->second.c_str(), 1/*overwrite*/))
exit(127);
_exit(127);
}
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
for (size_t i = 0; i < argv.size(); i++)
argv_cstr[i] = const_cast<char*>(argv[i].c_str());
argv_cstr[argv.size()] = NULL;

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

@ -1,3 +1,4 @@
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@ -25,6 +26,7 @@
#include "base/sys_info.h"
#include "base/time.h"
#include "base/waitable_event.h"
#include "base/dir_reader_posix.h"
const int kMicrosecondsPerSecond = 1000000;
@ -86,6 +88,10 @@ bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
return result;
}
#ifdef ANDROID
typedef unsigned long int rlim_t;
#endif
// A class to handle auto-closing of DIR*'s.
class ScopedDIRClose {
public:
@ -97,19 +103,20 @@ class ScopedDIRClose {
};
typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR;
#ifdef ANDROID
typedef unsigned long int rlim_t;
#endif
void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
#if defined(OS_LINUX)
// DANGER: no calls to malloc are allowed from now on:
// http://crbug.com/36678
#if defined(ANDROID)
static const rlim_t kSystemDefaultMaxFds = 1024;
static const char kFDDir[] = "/proc/self/fd";
#elif defined(OS_LINUX)
static const rlim_t kSystemDefaultMaxFds = 8192;
static const char fd_dir[] = "/proc/self/fd";
static const char kFDDir[] = "/proc/self/fd";
#elif defined(OS_MACOSX)
static const rlim_t kSystemDefaultMaxFds = 256;
static const char fd_dir[] = "/dev/fd";
static const char kFDDir[] = "/dev/fd";
#endif
std::set<int> saved_fds;
// Get the maximum number of FDs possible.
struct rlimit nofile;
@ -125,52 +132,63 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
if (max_fds > INT_MAX)
max_fds = INT_MAX;
// Don't close stdin, stdout and stderr
saved_fds.insert(STDIN_FILENO);
saved_fds.insert(STDOUT_FILENO);
saved_fds.insert(STDERR_FILENO);
for (base::InjectiveMultimap::const_iterator
i = saved_mapping.begin(); i != saved_mapping.end(); ++i) {
saved_fds.insert(i->dest);
}
ScopedDIR dir_closer(opendir(fd_dir));
DIR *dir = dir_closer.get();
if (NULL == dir) {
DLOG(ERROR) << "Unable to open " << fd_dir;
DirReaderPosix fd_dir(kFDDir);
if (!fd_dir.IsValid()) {
// Fallback case: Try every possible fd.
for (rlim_t i = 0; i < max_fds; ++i) {
const int fd = static_cast<int>(i);
if (saved_fds.find(fd) != saved_fds.end())
if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
continue;
InjectiveMultimap::const_iterator j;
for (j = saved_mapping.begin(); j != saved_mapping.end(); j++) {
if (fd == j->dest)
break;
}
if (j != saved_mapping.end())
continue;
// Since we're just trying to close anything we can find,
// ignore any error return values of close().
HANDLE_EINTR(close(fd));
}
return;
}
struct dirent *ent;
while ((ent = readdir(dir))) {
const int dir_fd = fd_dir.fd();
for ( ; fd_dir.Next(); ) {
// Skip . and .. entries.
if (ent->d_name[0] == '.')
if (fd_dir.name()[0] == '.')
continue;
char *endptr;
errno = 0;
const long int fd = strtol(ent->d_name, &endptr, 10);
if (ent->d_name[0] == 0 || *endptr || fd < 0 || errno)
const long int fd = strtol(fd_dir.name(), &endptr, 10);
if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
continue;
if (saved_fds.find(fd) != saved_fds.end())
if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
continue;
InjectiveMultimap::const_iterator i;
for (i = saved_mapping.begin(); i != saved_mapping.end(); i++) {
if (fd == i->dest)
break;
}
if (i != saved_mapping.end())
continue;
if (fd == dir_fd)
continue;
// When running under Valgrind, Valgrind opens several FDs for its
// own use and will complain if we try to close them. All of
// these FDs are >= |max_fds|, so we can check against that here
// before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
if (fd < static_cast<int>(max_fds))
HANDLE_EINTR(close(fd));
if (fd < static_cast<int>(max_fds)) {
int ret = HANDLE_EINTR(close(fd));
if (ret != 0) {
DLOG(ERROR) << "Problem closing fd";
}
}
}
}
@ -419,6 +437,13 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
int pipe_fd[2];
pid_t pid;
// Illegal to allocate memory after fork and before execvp
InjectiveMultimap fd_shuffle1, fd_shuffle2;
fd_shuffle1.reserve(3);
fd_shuffle2.reserve(3);
const std::vector<std::string>& argv = cl.argv();
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
if (pipe(pipe_fd) < 0)
return false;
@ -429,27 +454,35 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
return false;
case 0: // child
{
// Obscure fork() rule: in the child, if you don't end up doing exec*(),
// you call _exit() instead of exit(). This is because _exit() does not
// call any previously-registered (in the parent) exit handlers, which
// might do things like block waiting for threads that don't even exist
// in the child.
int dev_null = open("/dev/null", O_WRONLY);
if (dev_null < 0)
exit(127);
_exit(127);
InjectiveMultimap fd_shuffle;
fd_shuffle.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
fd_shuffle.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
fd_shuffle.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
// Adding another element here? Remeber to increase the argument to
// reserve(), above.
if (!ShuffleFileDescriptors(fd_shuffle))
exit(127);
std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
std::back_inserter(fd_shuffle2));
CloseSuperfluousFds(fd_shuffle);
// fd_shuffle1 is mutated by this call because it cannot malloc.
if (!ShuffleFileDescriptors(&fd_shuffle1))
_exit(127);
CloseSuperfluousFds(fd_shuffle2);
const std::vector<std::string> argv = cl.argv();
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
for (size_t i = 0; i < argv.size(); i++)
argv_cstr[i] = const_cast<char*>(argv[i].c_str());
argv_cstr[argv.size()] = NULL;
execvp(argv_cstr[0], argv_cstr.get());
exit(127);
_exit(127);
}
default: // parent
{

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

@ -310,7 +310,7 @@ DEFINE_STATIC_SETTER(static_input_setter,
DEFINE_STATIC_SETTER(static_multiline_setter,
if (!JSVAL_IS_BOOLEAN(*vp) && !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp))
return false;
res->setMultiline(!!JSVAL_TO_BOOLEAN(*vp)))
res->setMultiline(cx, !!JSVAL_TO_BOOLEAN(*vp)))
const uint8 REGEXP_STATIC_PROP_ATTRS = JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE;
const uint8 RO_REGEXP_STATIC_PROP_ATTRS = REGEXP_STATIC_PROP_ATTRS | JSPROP_READONLY;

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

@ -191,11 +191,6 @@ LIBS_DESC_SUFFIX = @LIBS_DESC_SUFFIX@
USE_N32 = @USE_N32@
HAVE_64BIT_OS = @HAVE_64BIT_OS@
# Temp hack. It is not my intention to leave this crap in here for ever.
# Im talking to fur right now to solve the problem without introducing
# NS_USE_NATIVE to the build system -ramiro.
NS_USE_NATIVE = @NS_USE_NATIVE@
CC = @CC@
CXX = @CXX@

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

@ -2334,7 +2334,6 @@ ia64*-hpux*)
if test "$SOLARIS_SUNPRO_CC"; then
LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN:\$\$ORIGIN/..' -z lazyload -z combreloc -z muldefs"
LIBS="-lCrun -lCstd -lc $LIBS"
NS_USE_NATIVE=1
AC_DEFINE(NSCAP_DISABLE_DEBUG_PTR_TYPES)
CFLAGS="$CFLAGS -xlibmieee -xstrconst -xbuiltin=%all -D__FUNCTION__=__func__"
CXXFLAGS="$CXXFLAGS -xlibmieee -xbuiltin=%all -features=tmplife,tmplrefstatic,extensions -norunpath -D__FUNCTION__=__func__ -template=no%extdef"
@ -5079,7 +5078,6 @@ AC_SUBST(WINDRES)
AC_SUBST(IMPLIB)
AC_SUBST(FILTER)
AC_SUBST(BIN_FLAGS)
AC_SUBST(NS_USE_NATIVE)
AC_SUBST(MOZ_JS_LIBS)
AC_SUBST(MOZ_PSM)
AC_SUBST(MOZ_DEBUG)

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

@ -92,19 +92,18 @@ class BumpChunk
JS_ASSERT(bump == AlignPtr(bump));
}
void clobberUnused() {
#ifdef DEBUG
memset(bump, 0xcd, limit - bump);
#endif
}
void setBump(void *ptr) {
JS_ASSERT(bumpBase() <= ptr);
JS_ASSERT(ptr <= limit);
DebugOnly<char *> prevBump = bump;
bump = static_cast<char *>(ptr);
if (prevBump < bump)
clobberUnused();
#ifdef DEBUG
JS_ASSERT(contains(prevBump));
/* Clobber the now-free space. */
if (prevBump > bump)
memset(bump, 0xcd, prevBump - bump);
#endif
}
public:

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

@ -20,7 +20,7 @@ function assertRaises(exc, callback) {
try {
callback();
} catch (e) {
assertEq(e instanceof InternalError, true);
assertEq(e instanceof StopIteration, true);
caught = true;
}
assertEq(caught, true);

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

@ -0,0 +1,12 @@
// visibility of updates to RegExp.multiline
function foo(value) {
for (var i = 0; i < 50; i++) {
var re = /erwe/;
assertEq(re.multiline, value);
}
}
foo(false);
RegExp.multiline = true;
foo(true);

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

@ -45,7 +45,6 @@ eval("assertStackIs(['eval-code', 'global-code'])");
this['eval']("assertStackIs(['eval-code', eval, 'global-code'])");
eval.bind(null, "assertStackIs(['eval-code', eval, 'bound(eval)', 'global-code'])")();
(function f() { assertStackIs([f, Function.prototype.call, 'global-code']) }).call(null);
(function f() { assertStackIs([f, Function.prototype.apply, 'global-code']) }).apply(null, {});
(function f() { (function g(x,y,z) { assertStackIs([g,f,'global-code']); })() })(1);
/***********/
@ -135,10 +134,9 @@ new proxy();
/***********/
for (var i = 0; i < 10; ++i) {
eval("'no imacros please'");
/* No loss for scripts. */
(function f() {
assertStackIs([f, Function.prototype.apply, 'global-code']);
}).apply(null, {});
(function f() {
assertStackIs([f, Function.prototype.call, 'global-code']);
}).call(null);
@ -155,26 +153,4 @@ for (var i = 0; i < 10; ++i) {
assertEq(stack[1], Function.prototype.call);
}
}).bind().call(null);
(function f() {
var stack = dumpStack();
assertEq(stack[0], f);
if (stack.length === 4) {
assertEq(stack[1].name, 'f');
assertEq(stack[2], Function.prototype.apply);
} else {
assertEq(stack.length, 3);
assertEq(stack[1], Function.prototype.apply);
}
}).bind().apply(null, {});
(function f() {
var stack = dumpStack();
assertEq(stack[0], f);
if (stack.length === 4) {
assertEq(stack[1].name, 'f');
assertEq(stack[2], Function.prototype.apply);
} else {
assertEq(stack.length, 3);
assertEq(stack[1], Function.prototype.apply);
}
}).bind().apply(null, [1,2,3,4,5]);
}

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

@ -5944,7 +5944,7 @@ JS_SetRegExpInput(JSContext *cx, JSObject *obj, JSString *input, JSBool multilin
CHECK_REQUEST(cx);
assertSameCompartment(cx, input);
obj->asGlobal()->getRegExpStatics()->reset(input, !!multiline);
obj->asGlobal()->getRegExpStatics()->reset(cx, input, !!multiline);
}
JS_PUBLIC_API(void)

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

@ -301,37 +301,40 @@ enum {
* Some objects are not dense arrays, or are dense arrays whose length
* property does not fit in an int32.
*/
OBJECT_FLAG_NON_DENSE_ARRAY = 0x0010000,
OBJECT_FLAG_NON_DENSE_ARRAY = 0x00010000,
/* Whether any objects this represents are not packed arrays. */
OBJECT_FLAG_NON_PACKED_ARRAY = 0x0020000,
OBJECT_FLAG_NON_PACKED_ARRAY = 0x00020000,
/* Whether any objects this represents are not typed arrays. */
OBJECT_FLAG_NON_TYPED_ARRAY = 0x0040000,
OBJECT_FLAG_NON_TYPED_ARRAY = 0x00040000,
/* Whether any represented script has had arguments objects created. */
OBJECT_FLAG_CREATED_ARGUMENTS = 0x0080000,
OBJECT_FLAG_CREATED_ARGUMENTS = 0x00080000,
/* Whether any represented script is considered uninlineable. */
OBJECT_FLAG_UNINLINEABLE = 0x0100000,
OBJECT_FLAG_UNINLINEABLE = 0x00100000,
/* Whether any objects have an equality hook. */
OBJECT_FLAG_SPECIAL_EQUALITY = 0x0200000,
OBJECT_FLAG_SPECIAL_EQUALITY = 0x00200000,
/* Whether any objects have been iterated over. */
OBJECT_FLAG_ITERATED = 0x0400000,
OBJECT_FLAG_ITERATED = 0x00400000,
/* Outer function which has been marked reentrant. */
OBJECT_FLAG_REENTRANT_FUNCTION = 0x0800000,
OBJECT_FLAG_REENTRANT_FUNCTION = 0x00800000,
/* For a global object, whether flags were set on the RegExpStatics. */
OBJECT_FLAG_REGEXP_FLAGS_SET = 0x01000000,
/* Flags which indicate dynamic properties of represented objects. */
OBJECT_FLAG_DYNAMIC_MASK = 0x0ff0000,
OBJECT_FLAG_DYNAMIC_MASK = 0x01ff0000,
/*
* Whether all properties of this object are considered unknown.
* If set, all flags in DYNAMIC_MASK will also be set.
*/
OBJECT_FLAG_UNKNOWN_PROPERTIES = 0x1000000,
OBJECT_FLAG_UNKNOWN_PROPERTIES = 0x80000000,
/* Mask for objects created with unknown properties. */
OBJECT_FLAG_UNKNOWN_MASK =

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

@ -574,8 +574,7 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
if (obj) {
/* Enumerate Iterator.prototype directly. */
JSIteratorOp op = obj->getClass()->ext.iteratorObject;
if (op && (obj->getClass() != &IteratorClass || obj->getNativeIterator())) {
if (JSIteratorOp op = obj->getClass()->ext.iteratorObject) {
JSObject *iterobj = op(cx, obj, !(flags & JSITER_FOREACH));
if (!iterobj)
return false;
@ -973,14 +972,12 @@ js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
if (iterobj->isIterator()) {
/* Key iterators are handled by fast-paths. */
ni = iterobj->getNativeIterator();
if (ni) {
bool more = ni->props_cursor < ni->props_end;
if (ni->isKeyIter() || !more) {
rval->setBoolean(more);
return true;
}
}
}
/* We might still have a pending value. */
if (!cx->iterValue.isMagic(JS_NO_ITER_VALUE)) {
@ -1033,7 +1030,7 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
* read-only and permanent.
*/
NativeIterator *ni = iterobj->getNativeIterator();
if (ni && ni->isKeyIter()) {
if (ni->isKeyIter()) {
JS_ASSERT(ni->props_cursor < ni->props_end);
*rval = IdToValue(*ni->current());
ni->incCursor();
@ -1459,6 +1456,14 @@ InitIteratorClass(JSContext *cx, GlobalObject *global)
if (!iteratorProto)
return false;
AutoIdVector blank(cx);
NativeIterator *ni = NativeIterator::allocateIterator(cx, 0, blank);
if (!ni)
return false;
ni->init(NULL, 0 /* flags */, 0, 0);
iteratorProto->setNativeIterator(ni);
JSFunction *ctor = global->createConstructor(cx, Iterator, &IteratorClass,
CLASS_ATOM(cx, Iterator), 2);
if (!ctor)

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

@ -1539,8 +1539,8 @@ MatchCallback(JSContext *cx, RegExpStatics *res, size_t count, void *p)
return res->createLastMatch(cx, &v) && arrayobj->defineElement(cx, count, v);
}
static JSBool
str_match(JSContext *cx, uintN argc, Value *vp)
JSBool
js::str_match(JSContext *cx, uintN argc, Value *vp)
{
JSString *str = ThisToStringForStringProto(cx, vp);
if (!str)
@ -1572,8 +1572,8 @@ str_match(JSContext *cx, uintN argc, Value *vp)
return true;
}
static JSBool
str_search(JSContext *cx, uintN argc, Value *vp)
JSBool
js::str_search(JSContext *cx, uintN argc, Value *vp)
{
JSString *str = ThisToStringForStringProto(cx, vp);
if (!str)
@ -2436,8 +2436,8 @@ class SplitStringMatcher {
};
/* ES5 15.5.4.14 */
static JSBool
str_split(JSContext *cx, uintN argc, Value *vp)
JSBool
js::str_split(JSContext *cx, uintN argc, Value *vp)
{
/* Steps 1-2. */
JSString *str = ThisToStringForStringProto(cx, vp);

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

@ -337,6 +337,15 @@ FileEscapedString(FILE *fp, JSLinearString *str, uint32 quote)
return PutEscapedStringImpl(NULL, 0, fp, str, quote) != size_t(-1);
}
JSBool
str_match(JSContext *cx, uintN argc, Value *vp);
JSBool
str_search(JSContext *cx, uintN argc, Value *vp);
JSBool
str_split(JSContext *cx, uintN argc, Value *vp);
} /* namespace js */
extern JSBool

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

@ -1305,10 +1305,15 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
storePtr(ImmPtr((void *) templateObject->capacity), Address(result, offsetof(JSObject, capacity)));
storePtr(ImmPtr(templateObject->type()), Address(result, JSObject::offsetOfType()));
/* Fixed slots of non-array objects are required to be initialized. */
/*
* Fixed slots of non-array objects are required to be initialized;
* Use the values currently in the template object.
*/
if (!templateObject->isDenseArray()) {
for (unsigned i = 0; i < templateObject->numFixedSlots(); i++)
storeValue(UndefinedValue(), Address(result, JSObject::getFixedSlotOffset(i)));
for (unsigned i = 0; i < templateObject->numFixedSlots(); i++) {
storeValue(templateObject->getFixedSlot(i),
Address(result, JSObject::getFixedSlotOffset(i)));
}
}
return jump;

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

@ -61,9 +61,15 @@
#include "jsopcodeinlines.h"
#include "jshotloop.h"
#include "builtin/RegExp.h"
#include "vm/RegExpStatics.h"
#include "vm/RegExpObject.h"
#include "jsautooplen.h"
#include "jstypedarrayinlines.h"
#include "vm/RegExpObject-inl.h"
using namespace js;
using namespace js::mjit;
#if defined(JS_POLYIC) || defined(JS_MONOIC)
@ -2719,14 +2725,7 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_SETGNAME)
BEGIN_CASE(JSOP_REGEXP)
{
JSObject *regex = script->getRegExp(fullAtomIndex(PC));
prepareStubCall(Uses(0));
masm.move(ImmPtr(regex), Registers::ArgReg1);
INLINE_STUBCALL(stubs::RegExp, REJOIN_PUSH_OBJECT);
frame.takeReg(Registers::ReturnReg);
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
}
jsop_regexp();
END_CASE(JSOP_REGEXP)
BEGIN_CASE(JSOP_OBJECT)
@ -6576,6 +6575,87 @@ mjit::Compiler::jsop_newinit()
return true;
}
void
mjit::Compiler::jsop_regexp()
{
JSObject *obj = script->getRegExp(fullAtomIndex(PC));
RegExpStatics *res = globalObj ? globalObj->getRegExpStatics() : NULL;
if (!globalObj ||
!cx->typeInferenceEnabled() ||
analysis->localsAliasStack() ||
types::TypeSet::HasObjectFlags(cx, globalObj->getType(cx),
types::OBJECT_FLAG_REGEXP_FLAGS_SET)) {
prepareStubCall(Uses(0));
masm.move(ImmPtr(obj), Registers::ArgReg1);
INLINE_STUBCALL(stubs::RegExp, REJOIN_FALLTHROUGH);
frame.pushSynced(JSVAL_TYPE_OBJECT);
return;
}
RegExpPrivate *regexp = static_cast<RegExpObject *>(obj)->getPrivate();
DebugOnly<uint32> origFlags = regexp->getFlags();
DebugOnly<uint32> staticsFlags = res->getFlags();
JS_ASSERT((origFlags & staticsFlags) == staticsFlags);
/*
* JS semantics require regular expression literals to create different
* objects every time they execute. We only need to do this cloning if the
* script could actually observe the effect of such cloning, by getting
* or setting properties on it. Particular RegExp and String natives take
* regular expressions as 'this' or an argument, and do not let that
* expression escape and be accessed by the script, so avoid cloning in
* these cases.
*/
analyze::SSAUseChain *uses =
analysis->useChain(analyze::SSAValue::PushedValue(PC - script->code, 0));
if (uses && uses->popped && !uses->next) {
jsbytecode *use = script->code + uses->offset;
uint32 which = uses->u.which;
if (JSOp(*use) == JSOP_CALLPROP) {
JSObject *callee = analysis->pushedTypes(use, 0)->getSingleton(cx);
if (callee && callee->isFunction()) {
Native native = callee->getFunctionPrivate()->maybeNative();
if (native == js::regexp_exec || native == js::regexp_test) {
frame.push(ObjectValue(*obj));
return;
}
}
} else if (JSOp(*use) == JSOP_CALL && which == 0) {
uint32 argc = GET_ARGC(use);
JSObject *callee = analysis->poppedTypes(use, argc + 1)->getSingleton(cx);
if (callee && callee->isFunction() && argc >= 1 && which == argc - 1) {
Native native = callee->getFunctionPrivate()->maybeNative();
if (native == js::str_match ||
native == js::str_search ||
native == js::str_replace ||
native == js::str_split) {
frame.push(ObjectValue(*obj));
return;
}
}
}
}
RegisterID result = frame.allocReg();
Jump emptyFreeList = masm.getNewObject(cx, result, obj);
stubcc.linkExit(emptyFreeList, Uses(0));
stubcc.leave();
stubcc.masm.move(ImmPtr(obj), Registers::ArgReg1);
OOL_STUBCALL(stubs::RegExp, REJOIN_FALLTHROUGH);
/* Bump the refcount on the wrapped RegExp. */
size_t *refcount = regexp->addressOfRefCount();
masm.add32(Imm32(1), AbsoluteAddress(refcount));
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, result);
stubcc.rejoin(Changes(1));
}
bool
mjit::Compiler::startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget)
{

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

@ -711,6 +711,7 @@ private:
bool jsop_arginc(JSOp op, uint32 slot);
bool jsop_localinc(JSOp op, uint32 slot);
bool jsop_newinit();
void jsop_regexp();
void jsop_initmethod();
void jsop_initprop();
void jsop_initelem();

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

@ -1430,7 +1430,7 @@ stubs::DefLocalFun_FC(VMFrame &f, JSFunction *fun)
return obj;
}
JSObject * JS_FASTCALL
void JS_FASTCALL
stubs::RegExp(VMFrame &f, JSObject *regex)
{
/*
@ -1443,12 +1443,12 @@ stubs::RegExp(VMFrame &f, JSObject *regex)
*/
JSObject *proto;
if (!js_GetClassPrototype(f.cx, &f.fp()->scopeChain(), JSProto_RegExp, &proto))
THROWV(NULL);
THROW();
JS_ASSERT(proto);
JSObject *obj = js_CloneRegExpObject(f.cx, regex, proto);
if (!obj)
THROWV(NULL);
return obj;
THROW();
f.regs.sp[0].setObject(*obj);
}
JSObject * JS_FASTCALL

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

@ -152,7 +152,7 @@ void JS_FASTCALL SetConst(VMFrame &f, JSAtom *atom);
template<JSBool strict> void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL DefLocalFun(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL DefLocalFun_FC(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
void JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
JSObject * JS_FASTCALL Lambda(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL LambdaJoinableForInit(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL LambdaJoinableForSet(VMFrame &f, JSFunction *fun);

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

@ -46,6 +46,7 @@
#include "jsobjinlines.h"
#include "jsstrinlines.h"
#include "RegExpStatics-inl.h"
inline js::RegExpObject *
JSObject::asRegExp()

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

@ -284,6 +284,9 @@ class RegExpPrivate
void incref(JSContext *cx);
void decref(JSContext *cx);
/* For JIT access. */
size_t *addressOfRefCount() { return &refCount; }
/* Accessors */
JSLinearString *getSource() const { return source; }

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

@ -181,6 +181,45 @@ RegExpStatics::getRightContext(JSSubString *out) const
out->length = matchPairsInput->length() - get(0, 1);
}
inline void
RegExpStatics::setMultiline(JSContext *cx, bool enabled)
{
aboutToWrite();
if (enabled) {
flags = RegExpFlag(flags | MultilineFlag);
markFlagsSet(cx);
} else {
flags = RegExpFlag(flags & ~MultilineFlag);
}
}
inline void
RegExpStatics::markFlagsSet(JSContext *cx)
{
/*
* Flags set on the RegExp function get propagated to constructed RegExp
* objects, which interferes with optimizations that inline RegExp cloning
* or avoid cloning entirely. Scripts making this assumption listen to
* type changes on RegExp.prototype, so mark a state change to trigger
* recompilation of all such code (when recompiling, a stub call will
* always be performed).
*/
GlobalObject *global = GetGlobalForScopeChain(cx);
JS_ASSERT(this == global->getRegExpStatics());
types::MarkTypeObjectFlags(cx, global, types::OBJECT_FLAG_REGEXP_FLAGS_SET);
}
inline void
RegExpStatics::reset(JSContext *cx, JSString *newInput, bool newMultiline)
{
aboutToWrite();
clear();
pendingInput = newInput;
setMultiline(cx, newMultiline);
checkInvariants();
}
} /* namespace js */
#endif

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

@ -148,6 +148,8 @@ class RegExpStatics
*/
bool makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const;
void markFlagsSet(JSContext *cx);
struct InitBuffer {};
explicit RegExpStatics(InitBuffer) : bufferLink(NULL), copied(false) {}
@ -157,7 +159,6 @@ class RegExpStatics
RegExpStatics() : bufferLink(NULL), copied(false) { clear(); }
static JSObject *create(JSContext *cx, GlobalObject *parent);
static RegExpStatics *extractFrom(GlobalObject *globalObj);
/* Mutators. */
@ -177,13 +178,7 @@ class RegExpStatics
return true;
}
void setMultiline(bool enabled) {
aboutToWrite();
if (enabled)
flags = RegExpFlag(flags | MultilineFlag);
else
flags = RegExpFlag(flags & ~MultilineFlag);
}
inline void setMultiline(JSContext *cx, bool enabled);
void clear() {
aboutToWrite();
@ -194,13 +189,7 @@ class RegExpStatics
}
/* Corresponds to JSAPI functionality to set the pending RegExp input. */
void reset(JSString *newInput, bool newMultiline) {
aboutToWrite();
clear();
pendingInput = newInput;
setMultiline(newMultiline);
checkInvariants();
}
inline void reset(JSContext *cx, JSString *newInput, bool newMultiline);
void setPendingInput(JSString *newInput) {
aboutToWrite();

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

@ -1028,19 +1028,20 @@ StackIter::settleOnNewState()
*
* regs.sp == vp + 2 + argc
*
* The mjit Function.prototype.apply optimization breaks this
* invariant (see ic::SplatApplyArgs). Thus, for JSOP_FUNAPPLY we
* need to (slowly) reconstruct the depth.
*
* Additionally, the Function.prototype.{call,apply} optimizations
* leave no record when 'this' is a native function. Thus, if the
* following expression runs and breaks in the debugger, the call
* to 'replace' will not appear on the callstack.
* The Function.prototype.call optimization leaves no record when
* 'this' is a native function. Thus, if the following expression
* runs and breaks in the debugger, the call to 'replace' will not
* appear on the callstack.
*
* (String.prototype.replace).call('a',/a/,function(){debugger});
*
* Function.prototype.call will however appear, hence the debugger
* can, by inspecting 'args.thisv', give some useful information.
*
* For Function.prototype.apply, the situation is even worse: since
* a dynamic number of arguments have been pushed onto the stack
* (see SplatApplyArgs), there is no efficient way to know how to
* find the callee. Thus, calls to apply are lost completely.
*/
JSOp op = js_GetOpcode(cx_, fp_->script(), pc_);
if (op == JSOP_CALL || op == JSOP_FUNCALL) {
@ -1056,30 +1057,12 @@ StackIter::settleOnNewState()
args_ = CallArgsFromVp(argc, vp);
return;
}
} else if (op == JSOP_FUNAPPLY) {
JS_ASSERT(!fp_->hasImacropc());
uintN argc = GET_ARGC(pc_);
uintN spoff = js_ReconstructStackDepth(cx_, fp_->script(), pc_);
Value *sp = fp_->base() + spoff;
Value *vp = sp - (2 + argc);
CrashIfInvalidSlot(fp_, vp);
if (IsNativeFunction(*vp)) {
if (sp_ != sp) {
JS_ASSERT(argc == 2);
JS_ASSERT(vp[0].toObject().getFunctionPrivate()->native() == js_fun_apply);
JS_ASSERT(sp_ >= vp + 3);
argc = sp_ - (vp + 2);
}
state_ = IMPLICIT_NATIVE;
args_ = CallArgsFromVp(argc, vp);
return;
}
}
state_ = SCRIPTED;
JS_ASSERT(sp_ >= fp_->base() && sp_ <= fp_->slots() + fp_->script()->nslots);
DebugOnly<JSScript *> script = fp_->script();
JS_ASSERT_IF(op != JSOP_FUNAPPLY,
sp_ >= fp_->base() && sp_ <= fp_->slots() + script->nslots);
JS_ASSERT_IF(!fp_->hasImacropc(),
pc_ >= script->code && pc_ < script->code + script->length);
return;

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

@ -1175,9 +1175,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
&triedToWrap);
if(!flat && triedToWrap)
return JS_FALSE;
if (!flat) {
flat = ConstructProxyObject(ccx, aHelper, xpcscope);
}
}
if(flat) {

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

@ -2370,10 +2370,6 @@ private:
};
class xpcObjectHelper;
JSObject *
ConstructProxyObject(XPCCallContext &ccx,
xpcObjectHelper &aHelper,
XPCWrappedNativeScope *xpcscope);
extern JSBool ConstructSlimWrapper(XPCCallContext &ccx,
xpcObjectHelper &aHelper,
XPCWrappedNativeScope* xpcScope,

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

@ -3923,34 +3923,6 @@ MorphSlimWrapper(JSContext *cx, JSObject *obj)
static PRUint32 sSlimWrappers;
#endif
JSObject *
ConstructProxyObject(XPCCallContext &ccx,
xpcObjectHelper &aHelper,
XPCWrappedNativeScope *xpcscope)
{
nsISupports *identityObj = aHelper.GetCanonical();
nsXPCClassInfo *classInfoHelper = aHelper.GetXPCClassInfo();
#ifdef DEBUG
{
JSUint32 flagsInt;
nsresult debug_rv = classInfoHelper->GetScriptableFlags(&flagsInt);
XPCNativeScriptableFlags flags(flagsInt);
NS_ASSERTION(NS_SUCCEEDED(debug_rv) && flags.WantPreCreate(),
"bad flags, cache->IsProxy() implies WantPreCreate()");
}
#endif
// We re-use the PreCreate hook to create the actual proxy object.
JSObject* parent = xpcscope->GetGlobalJSObject();
nsresult rv = classInfoHelper->PreCreate(identityObj, ccx, parent, &parent);
NS_ENSURE_SUCCESS(rv, nsnull);
nsWrapperCache *cache = aHelper.GetWrapperCache();
JSObject *flat = cache->GetWrapper();
return flat;
}
JSBool
ConstructSlimWrapper(XPCCallContext &ccx,
xpcObjectHelper &aHelper,

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

@ -277,11 +277,11 @@ TextOverflow::WillProcessLines(nsDisplayListBuilder* aBuilder,
scroll->GetScrollbarStyles().mHorizontal != NS_STYLE_OVERFLOW_HIDDEN;
textOverflow->mContentArea.MoveBy(scroll->GetScrollPosition());
}
textOverflow->mBlockIsRTL =
aBlockFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
PRUint8 direction = aBlockFrame->GetStyleVisibility()->mDirection;
textOverflow->mBlockIsRTL = direction == NS_STYLE_DIRECTION_RTL;
const nsStyleTextReset* style = aBlockFrame->GetStyleTextReset();
textOverflow->mLeft.Init(style->mTextOverflow.mLeft);
textOverflow->mRight.Init(style->mTextOverflow.mRight);
textOverflow->mLeft.Init(style->mTextOverflow.GetLeft(direction));
textOverflow->mRight.Init(style->mTextOverflow.GetRight(direction));
// The left/right marker string is setup in ExamineLineFrames when a line
// has overflow on that side.
@ -402,31 +402,44 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges)
{
// No ellipsing for 'clip' style.
bool suppressLeft = mLeft.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
bool suppressRight = mRight.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
if (mCanHaveHorizontalScrollbar) {
nsIScrollableFrame* scroll = nsLayoutUtils::GetScrollableFrameFor(mBlock);
nsPoint pos = scroll->GetScrollPosition();
nsRect scrollRange = scroll->GetScrollRange();
// No ellipsing when nothing to scroll to on that side (this includes
// overflow:auto that doesn't trigger a horizontal scrollbar).
if (pos.x <= scrollRange.x) {
suppressLeft = true;
}
if (pos.x >= scrollRange.XMost()) {
suppressRight = true;
}
}
// Scrolling to the end position can leave some text still overflowing due to
// pixel snapping behaviour in our scrolling code so we move the edges 1px
// outward to avoid triggering a text-overflow marker for such overflow.
nsRect contentArea = mContentArea;
const nscoord scrollAdjust = mCanHaveHorizontalScrollbar ?
mBlock->PresContext()->AppUnitsPerDevPixel() : 0;
InflateLeft(&contentArea,
mLeft.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP,
scrollAdjust);
InflateRight(&contentArea,
mRight.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP,
scrollAdjust);
InflateLeft(&contentArea, suppressLeft, scrollAdjust);
InflateRight(&contentArea, suppressRight, scrollAdjust);
nsRect lineRect = aLine->GetScrollableOverflowArea();
const bool leftOverflow = lineRect.x < contentArea.x;
const bool rightOverflow = lineRect.XMost() > contentArea.XMost();
const bool leftOverflow =
!suppressLeft && lineRect.x < contentArea.x;
const bool rightOverflow =
!suppressRight && lineRect.XMost() > contentArea.XMost();
if (!leftOverflow && !rightOverflow) {
// The line does not overflow - no need to traverse the frame tree.
// The line does not overflow on a side we should ellipsize.
return;
}
PRUint32 pass = 0;
bool guessLeft =
mLeft.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP && leftOverflow;
bool guessRight =
mRight.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP && rightOverflow;
bool guessLeft = leftOverflow;
bool guessRight = rightOverflow;
do {
// Setup marker strings as needed.
if (guessLeft) {

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

@ -0,0 +1,18 @@
<!DOCTYPE html><html><head><script>
function boom()
{
var a = document.getElementsByTagName('div')[0];
var b = a.firstChild;
var r = document.createRange();
r.setStart(b, 1);
r.setEnd(a, 1);
var s = document.createRange();
s.setStart(b, 0);
s.setEnd(a, 1);
s.deleteContents();
}
</script></head><body onload="boom();">
<div>b</div>
</body></html>

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

@ -0,0 +1,15 @@
<!DOCTYPE html><html><head><script>
function boom()
{
var a = document.getElementsByTagName('div')[0];
var b = a.firstChild;
var r = document.createRange();
r.setStart(b, 1);
r.setEnd(a, 1);
b.splitText(0);
}
</script></head><body onload="boom();">
<div>b</div>
</body></html>

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

@ -379,3 +379,5 @@ asserts(14) asserts-if(Android,8) load 673770.html # bug 569193 and bug 459597
load 679933-1.html
load 682649-1.html
load 683702-1.xhtml
load 688996-1.html
load 688996-2.html

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

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p><canvas width="500" height="200" id="c"></canvas></p>
<script type="text/javascript">
const t1 = '你好';
const t2 = 'Hello';
var c = document.getElementById('c').getContext('2d');
c.font = 'serif';
c.fontSize = '15';
c.fillText(t1, 10, 100);
c.fillText(t2, 10, 100);
</script>
</body>
</html>

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p><canvas width="500" height="200" id="c"></canvas></p>
<script type="text/javascript">
const t = '你好Hello';
var c = document.getElementById('c').getContext('2d');
c.font = 'serif';
c.fontSize = '15';
c.fillText(t, 10, 100);
</script>
</body>
</html>

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

@ -67,3 +67,6 @@ fails == ctm-singular-sanity.html data:text/html,<body>Pass # Bug 612033
fails-if(cocoaWidget) == 672646-alpha-radial-gradient.html 672646-alpha-radial-gradient-ref.html # Bug 673333
== 674003-alpha-radial-gradient-superlum.html 674003-alpha-radial-gradient-superlum-ref.html
!= 693610-1.html 693610-1-notref.html # bug 693610: multiple glyph runs should not be overprinted

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

@ -16,6 +16,7 @@ var tests = [
[ {endNode:1}, [0,4], "012345678", "" ],
[ {endNode:1}, [0,4], "01234567", "8" ],
[ {endNode:1}, [1,4], "0", "12345678" ],
[ {startOffset:1,endNode:1}, [0,0], "0", "12345678" ],
[ {endNode:2}, [1,4], "0", "12345", "678" ],
]

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

@ -0,0 +1,12 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect height="100%" width="100%" fill="lime" />
<!-- The filter shouldn't resolve, so this should be transparent: -->
<rect height="100%" width="100%" fill="red"
filter="url(../filters.svg#NonWhiteToBlack)"/>
</svg>

После

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

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

@ -0,0 +1,38 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE svg [
<!-- entities etc. here -->
<!ENTITY dataURI
"data:image/svg+xml,&lt;svg xmlns='http://www.w3.org/2000/svg'&gt;&lt;g id='empty'/&gt;&lt;mask id='mask' maskContentUnits='userSpaceOnUse'&gt;&lt;rect width='50' height='50' fill='white'/&gt;&lt;/mask&gt;&lt;/svg&gt;">
]>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Testcase for bug 686013: CSS mask targeting a fragment in a data URI
</title>
<style type="text/css">
.masked {
mask: url("&dataURI;#mask");
}
</style>
<!-- use an empty g to force resource document to load before onload -->
<use xlink:href="&dataURI;#empty"/>
<!-- giant lime background -->
<rect width="100%" height="100%" fill="lime"/>
<!-- Masked red rect, covered by lime rect
(to make sure mask doesn't let too much through) -->
<rect width="75" height="75" fill="red" class="masked"/>
<rect width="50" height="50" fill="lime"/>
<!-- Masked lime rect, covering red rect
(to make sure mask lets enough through) -->
<g transform="translate(0, 100)">
<rect width="50" height="50" fill="red"/>
<rect width="75" height="75" fill="lime" class="masked"/>
</g>
</svg>

После

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

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

@ -105,6 +105,7 @@ random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
== use-01.svg pass.svg
== use-01-extref.svg pass.svg
== use-02-extref.svg use-02-extref-ref.svg
== use-extref-dataURI-01.svg pass.svg
== use-children.svg pass.svg
== fallback-color-01a.svg pass.svg
== fallback-color-01b.svg pass.svg
@ -116,6 +117,7 @@ random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
== filter-basic-03.svg pass.svg
== filter-bounds-01.svg pass.svg
== filter-bounds-02.svg pass.svg
== filter-extref-differentOrigin-01.svg pass.svg
== filter-foreignObject-01.svg pass.svg
== filter-invalidation-01.svg pass.svg
== filter-scaled-01.svg pass.svg
@ -146,6 +148,7 @@ fails == inline-in-xul-basic-01.xul pass.svg
== marker-viewBox-01.svg marker-viewBox-01-ref.svg
== mask-basic-01.svg pass.svg
== mask-basic-02.svg mask-basic-02-ref.svg
== mask-extref-dataURI-01.svg pass.svg
== mask-containing-masked-content-01.svg pass.svg
== mask-transformed-01.svg mask-transformed-01-ref.svg
== nested-viewBox-01.svg pass.svg

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

@ -0,0 +1,12 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Testcase for bug 686013: &lt;use&gt; targeting a fragment in a data URI
</title>
<rect fill="red" height="100%" width="100%"/>
<use xlink:href="data:image/svg+xml,&lt;svg xmlns='http://www.w3.org/2000/svg'&gt;&lt;rect id='target' height='100%' width='100%' fill='lime'/&gt;&lt;rect height='100%' width='100%' fill='orange'/&gt;&lt;/svg&gt;#target"/>
</svg>

После

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

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

@ -17,7 +17,7 @@ html,body {
}
.test {
overflow:auto;
text-overflow:ellipsis;
text-overflow:ellipsis ellipsis;
white-space:nowrap;
width: 4.4em;
margin-bottom:1em;

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

@ -31,7 +31,7 @@ html,body {
}
.o {
text-overflow: ellipsis;
text-overflow: ellipsis ellipsis;
color:blue;
}
.o span {

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

@ -19,7 +19,7 @@ html,body {
.test {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-overflow: ellipsis ellipsis;
color: black;
height: 6em;
width: 32.5em;

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

@ -134,6 +134,8 @@ x1 m { position:absolute; right:0; font-size:16px; }
#test9b { top:320px; left:100px; position:absolute; border:1px solid black; }
#test9c { top:320px; left:200px; position:absolute; border:1px solid black; }
#test9d { top:320px; left:300px; position:absolute; border:1px solid black; }
#test10a { top:360px; left:0; position:absolute; }
#test10b { top:360px; left:100px; position:absolute; }
</style>
</head>
@ -299,6 +301,9 @@ x1 m { position:absolute; right:0; font-size:16px; }
<div id="test9c"><div class="s a"><div class="p ltr"><span class="e"></span><i>&nbsp;&nbsp;&nbsp;&nbsp;</i><m>&#x2026;</m><span class="e a"></span></div></div></div>
<div id="test9d"><div class="s a"><div class="p rtl"><span class="e"></span><i>&nbsp;&nbsp;&nbsp;&nbsp;</i><m>&#x2026;</m><span class="e a"></span></div></div></div>
<!-- no marker for overflow:auto that doesn't trigger scrollbar -->
<div id="test10a"><div class="s a"><div class="p o ltr"><span style="margin-left:-5px" >||||||</span></div></div></div>
<div id="test10b"><div class="s a"><div class="p o rtl"><span style="margin-right:-5px">||||||</span></div></div></div>
</div>
</body>

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

@ -30,7 +30,7 @@ html,body {
}
.o {
text-overflow: ellipsis;
text-overflow: ellipsis ellipsis;
}
.rel {
@ -50,6 +50,9 @@ html,body {
white-space:nowrap;
font-size:16px;
}
.auto {
overflow: auto;
}
.r {
text-align:right;
}
@ -131,6 +134,8 @@ i {
#test9b { top:320px; left:100px; position:absolute; border:1px solid black; }
#test9c { top:320px; left:200px; position:absolute; border:1px solid black; }
#test9d { top:320px; left:300px; position:absolute; border:1px solid black; }
#test10a { top:360px; left:0; position:absolute; }
#test10b { top:360px; left:100px; position:absolute; }
</style>
@ -191,7 +196,10 @@ i {
<div id="test9c"><div class="s a"><div class="p o ltr"><span class="e"></span><i>&nbsp;&nbsp;&nbsp;&nbsp;</i><span class="e"></span><span class="c5 a">|||</span></div></div></div>
<div id="test9d"><div class="s a"><div class="p o rtl"><span class="e"></span><i>&nbsp;&nbsp;&nbsp;&nbsp;</i><span class="e"></span><span class="c5 a">|||</span></div></div></div>
</div>
<!-- no marker for overflow:auto that doesn't trigger scrollbar -->
<div id="test10a"><div class="s a"><div class="p o ltr auto"><span style="margin-left:-5px" >||||||</span></div></div></div>
<div id="test10b"><div class="s a"><div class="p o rtl auto"><span style="margin-right:-5px">||||||</span></div></div></div>
</div>
</body>
</html>

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

@ -44,9 +44,9 @@ s {
direction:ltr;
}
.t1 { text-overflow:""; }
.t2 { text-overflow:"Hello World"; }
.t3 { text-overflow:"X"; }
.t1 { text-overflow:"" ""; }
.t2 { text-overflow:"Hello World" "Hello World"; }
.t3 { text-overflow:"X" "X"; }
</style>

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

@ -19,3 +19,4 @@ skip-if(Android) == clipped-elements.html clipped-elements-ref.html
== theme-overflow.html theme-overflow-ref.html
HTTP(..) == table-cell.html table-cell-ref.html
HTTP(..) == two-value-syntax.html two-value-syntax-ref.html
HTTP(..) == single-value.html single-value-ref.html

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

@ -23,7 +23,7 @@ html,body {
.test {
overflow:auto;
text-overflow:ellipsis;
text-overflow:ellipsis ellipsis;
white-space:nowrap;
width: 5em;
position:relative;

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

@ -0,0 +1,105 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow: <single value>, scrolled and non-scrolled tests, (bug 684266)
-->
<html class="reftest-wait"><head>
<title>text-overflow: &lt;single value&gt;, scrolled and non-scrolled tests, (bug 684266)</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff),url(DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
body {padding:10px 40px;}
div {
width:100px;
white-space:nowrap;
}
.hidden {overflow:hidden}
.auto {overflow:auto}
.autolong {overflow:auto; width:100%;}
.scroll {overflow:scroll}
.ltr { direction:ltr; unicode-bidi: bidi-override; }
.rtl { direction:rtl; unicode-bidi: bidi-override; }
.ltr.p { text-indent: -5px; padding-left: 40px; } /* overflow into padding, but not outside the padding edge */
.rtl.p { text-indent: -5px; padding-right: 40px; } /* overflow into padding, but not outside the padding edge */
.s { text-indent: -5px; } /* overflow start edge outside the padding edge */
div.ltr {
text-overflow: clip ellipsis;
}
div.rtl {
text-overflow: ellipsis clip;
}
</style>
<script>
function scrolldivs() {
var divs = document.getElementsByTagName('div');
for (i = 0; i < divs.length; ++i) {
var elm = divs[i];
if (elm.hasAttribute('scroll')) {
if (window.getComputedStyle(elm).direction == 'ltr')
elm.scrollLeft = 8;
else
elm.scrollLeft = -8;
}
}
document.documentElement.removeAttribute('class');
}
</script>
</head>
<body onload="scrolldivs()">
<div class="ltr start p hidden">A long line that does not break (overflow:hidden)</div>
<div class="ltr start p auto">A long line that does not break (overflow:auto)</div>
<div class="ltr start p autolong">A long line that does not break (overflow:auto)</div>
<div class="ltr start p scroll">A long line that does not break (overflow:scroll)</div>
<div class="ltr start s hidden">A long line that does not break (overflow:hidden)</div>
<div class="ltr start s auto">A long line that does not break (overflow:auto)</div>
<div class="ltr start s autolong">A long line that does not break (overflow:auto)</div>
<div class="ltr start s scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="ltr start p hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="ltr start p auto">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start p autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start p scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="ltr start s hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="ltr start s auto">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start s autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start s scroll">A long line that does not break (overflow:scroll)</div>
<div class="rtl" style="float:right">
<div class="rtl start p hidden">A long line that does not break (overflow:hidden)</div>
<div class="rtl start p auto">A long line that does not break (overflow:auto)</div>
<div class="rtl start p autolong">A long line that does not break (overflow:auto)</div>
<div class="rtl start p scroll">A long line that does not break (overflow:scroll)</div>
<div class="rtl start s hidden">A long line that does not break (overflow:hidden)</div>
<div class="rtl start s auto">A long line that does not break (overflow:auto)</div>
<div class="rtl start s autolong">A long line that does not break (overflow:auto)</div>
<div class="rtl start s scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="rtl start p hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="rtl start p auto">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start p autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start p scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="rtl start s hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="rtl start s auto">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start s autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start s scroll">A long line that does not break (overflow:scroll)</div>
</div>
</body>
</hml>

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

@ -0,0 +1,98 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow: <single value>, scrolled and non-scrolled tests, (bug 684266)
-->
<html class="reftest-wait"><head>
<title>text-overflow: &lt;single value&gt;, scrolled and non-scrolled tests, (bug 684266)</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff),url(DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
body {padding:10px 40px;}
div {
text-overflow: ellipsis;
width:100px;
white-space:nowrap;
}
.hidden {overflow:hidden}
.auto {overflow:auto}
.autolong {overflow:auto; width:100%;}
.scroll {overflow:scroll}
.ltr { direction:ltr; unicode-bidi: bidi-override; }
.rtl { direction:rtl; unicode-bidi: bidi-override; }
.ltr.p { text-indent: -5px; padding-left: 40px; } /* overflow into padding, but not outside the padding edge */
.rtl.p { text-indent: -5px; padding-right: 40px; } /* overflow into padding, but not outside the padding edge */
.s { text-indent: -5px; } /* overflow start edge outside the padding edge */
</style>
<script>
function scrolldivs() {
var divs = document.getElementsByTagName('div');
for (i = 0; i < divs.length; ++i) {
var elm = divs[i];
if (elm.hasAttribute('scroll')) {
if (window.getComputedStyle(elm).direction == 'ltr')
elm.scrollLeft = 8;
else
elm.scrollLeft = -8;
}
}
document.documentElement.removeAttribute('class');
}
</script>
</head>
<body onload="scrolldivs()">
<div class="ltr start p hidden">A long line that does not break (overflow:hidden)</div>
<div class="ltr start p auto">A long line that does not break (overflow:auto)</div>
<div class="ltr start p autolong">A long line that does not break (overflow:auto)</div>
<div class="ltr start p scroll">A long line that does not break (overflow:scroll)</div>
<div class="ltr start s hidden">A long line that does not break (overflow:hidden)</div>
<div class="ltr start s auto">A long line that does not break (overflow:auto)</div>
<div class="ltr start s autolong">A long line that does not break (overflow:auto)</div>
<div class="ltr start s scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="ltr start p hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="ltr start p auto">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start p autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start p scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="ltr start s hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="ltr start s auto">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start s autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="ltr start s scroll">A long line that does not break (overflow:scroll)</div>
<div class="rtl" style="float:right">
<div class="rtl start p hidden">A long line that does not break (overflow:hidden)</div>
<div class="rtl start p auto">A long line that does not break (overflow:auto)</div>
<div class="rtl start p autolong">A long line that does not break (overflow:auto)</div>
<div class="rtl start p scroll">A long line that does not break (overflow:scroll)</div>
<div class="rtl start s hidden">A long line that does not break (overflow:hidden)</div>
<div class="rtl start s auto">A long line that does not break (overflow:auto)</div>
<div class="rtl start s autolong">A long line that does not break (overflow:auto)</div>
<div class="rtl start s scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="rtl start p hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="rtl start p auto">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start p autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start p scroll">A long line that does not break (overflow:scroll)</div>
<div scroll class="rtl start s hidden">A long line that does not break (overflow:hidden)</div>
<div scroll class="rtl start s auto">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start s autolong">A long line that does not break (overflow:auto)</div>
<div scroll class="rtl start s scroll">A long line that does not break (overflow:scroll)</div>
</div>
</body>
</hml>

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

@ -7,7 +7,7 @@
<style type="text/css">
p {
overflow: hidden;
text-overflow: ellipsis;
text-overflow: ellipsis ellipsis;
width: 200px;
}
.r {

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

@ -23,3 +23,7 @@ random-if(Android) == basic-negcoord.xul basic-negcoord-ref.xul
!= text-shadow-selected-1.html text-shadow-selected-1-notref.html
== text-shadow-selected-1.html text-shadow-selected-1-ref.html
# bug 692744
== text-shadow-on-space-1.html text-shadow-on-space-1-ref.html

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div {
font: 24px serif;
text-shadow: 2px 2px 1px red;
}
</style>
</head>
<body>
<div>
The spaces should not have shadows!
</div>
</body>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div {
font: 24px serif;
text-shadow: 2px 2px 1px red;
}
</style>
</head>
<body>
<div>
The spaces should not have shadows!
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</div>
</body>

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

@ -8186,8 +8186,9 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue)
if (ParseVariant(right, VARIANT_KEYWORD | VARIANT_STRING,
nsCSSProps::kTextOverflowKTable))
aValue.SetPairValue(left, right);
else
aValue.SetPairValue(left, left);
else {
aValue = left;
}
return PR_TRUE;
}

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

@ -156,6 +156,8 @@ CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
NS_EVENT_STATE_TYPE_UNSUPPORTED)
CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
NS_EVENT_STATE_HANDLER_DISABLED)
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",

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

@ -2486,33 +2486,35 @@ nsIDOMCSSValue*
nsComputedDOMStyle::DoGetTextOverflow()
{
const nsStyleTextReset *style = GetStyleTextReset();
nsROCSSPrimitiveValue *left = GetROCSSPrimitiveValue();
if (style->mTextOverflow.mLeft.mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsROCSSPrimitiveValue *first = GetROCSSPrimitiveValue();
const nsStyleTextOverflowSide *side = style->mTextOverflow.GetFirstValue();
if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsString str;
nsStyleUtil::AppendEscapedCSSString(style->mTextOverflow.mLeft.mString, str);
left->SetString(str);
nsStyleUtil::AppendEscapedCSSString(side->mString, str);
first->SetString(str);
} else {
left->SetIdent(
nsCSSProps::ValueToKeywordEnum(style->mTextOverflow.mLeft.mType,
first->SetIdent(
nsCSSProps::ValueToKeywordEnum(side->mType,
nsCSSProps::kTextOverflowKTable));
}
if (style->mTextOverflow.mLeft == style->mTextOverflow.mRight) {
return left;
side = style->mTextOverflow.GetSecondValue();
if (!side) {
return first;
}
nsROCSSPrimitiveValue *right = GetROCSSPrimitiveValue();
if (style->mTextOverflow.mRight.mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsROCSSPrimitiveValue *second = GetROCSSPrimitiveValue();
if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsString str;
nsStyleUtil::AppendEscapedCSSString(style->mTextOverflow.mRight.mString, str);
right->SetString(str);
nsStyleUtil::AppendEscapedCSSString(side->mString, str);
second->SetString(str);
} else {
right->SetIdent(
nsCSSProps::ValueToKeywordEnum(style->mTextOverflow.mRight.mType,
second->SetIdent(
nsCSSProps::ValueToKeywordEnum(side->mType,
nsCSSProps::kTextOverflowKTable));
}
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
valueList->AppendCSSValue(left);
valueList->AppendCSSValue(right);
valueList->AppendCSSValue(first);
valueList->AppendCSSValue(second);
return valueList;
}

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

@ -3494,7 +3494,7 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
text->SetDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID);
}
// text-overflow: pair(enum|string), inherit, initial
// text-overflow: enum, string, pair(enum|string), inherit, initial
const nsCSSValue* textOverflowValue =
aRuleData->ValueForTextOverflow();
if (eCSSUnit_Initial == textOverflowValue->GetUnit()) {
@ -3502,7 +3502,26 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
} else if (eCSSUnit_Inherit == textOverflowValue->GetUnit()) {
canStoreInRuleTree = PR_FALSE;
text->mTextOverflow = parentText->mTextOverflow;
} else if (eCSSUnit_Enumerated == textOverflowValue->GetUnit()) {
// A single enumerated value.
SetDiscrete(*textOverflowValue, text->mTextOverflow.mRight.mType,
canStoreInRuleTree,
SETDSC_ENUMERATED, parentText->mTextOverflow.mRight.mType,
NS_STYLE_TEXT_OVERFLOW_CLIP, 0, 0, 0, 0);
text->mTextOverflow.mRight.mString.Truncate();
text->mTextOverflow.mLeft.mType = NS_STYLE_TEXT_OVERFLOW_CLIP;
text->mTextOverflow.mLeft.mString.Truncate();
text->mTextOverflow.mLogicalDirections = true;
} else if (eCSSUnit_String == textOverflowValue->GetUnit()) {
// A single string value.
text->mTextOverflow.mRight.mType = NS_STYLE_TEXT_OVERFLOW_STRING;
textOverflowValue->GetStringValue(text->mTextOverflow.mRight.mString);
text->mTextOverflow.mLeft.mType = NS_STYLE_TEXT_OVERFLOW_CLIP;
text->mTextOverflow.mLeft.mString.Truncate();
text->mTextOverflow.mLogicalDirections = true;
} else if (eCSSUnit_Pair == textOverflowValue->GetUnit()) {
// Two values were specified.
text->mTextOverflow.mLogicalDirections = false;
const nsCSSValuePair& textOverflowValue =
aRuleData->ValueForTextOverflow()->GetPairValue();

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

@ -1148,6 +1148,7 @@ struct nsStyleTextOverflowSide {
};
struct nsStyleTextOverflow {
nsStyleTextOverflow() : mLogicalDirections(true) {}
bool operator==(const nsStyleTextOverflow& aOther) const {
return mLeft == aOther.mLeft && mRight == aOther.mRight;
}
@ -1155,8 +1156,35 @@ struct nsStyleTextOverflow {
return !(*this == aOther);
}
nsStyleTextOverflowSide mLeft;
nsStyleTextOverflowSide mRight;
// Returns the value to apply on the left side.
const nsStyleTextOverflowSide& GetLeft(PRUint8 aDirection) const {
NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
mLeft : mRight;
}
// Returns the value to apply on the right side.
const nsStyleTextOverflowSide& GetRight(PRUint8 aDirection) const {
NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
mRight : mLeft;
}
// Returns the first value that was specified.
const nsStyleTextOverflowSide* GetFirstValue() const {
return mLogicalDirections ? &mRight : &mLeft;
}
// Returns the second value, or null if there was only one value specified.
const nsStyleTextOverflowSide* GetSecondValue() const {
return mLogicalDirections ? nsnull : &mRight;
}
nsStyleTextOverflowSide mLeft; // start side when mLogicalDirections is true
nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
bool mLogicalDirections; // true when only one value was specified
};
struct nsStyleTextReset {

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

@ -2568,8 +2568,8 @@ var gCSSProperties = {
domProp: "textOverflow",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "clip", "clip clip" ],
other_values: [ "ellipsis", '""', "''", '"hello"', 'clip ellipsis', 'clip ""', '"hello" ""', '"" ellipsis' ],
initial_values: [ "clip" ],
other_values: [ "ellipsis", '""', "''", '"hello"', 'clip clip', 'ellipsis ellipsis', 'clip ellipsis', 'clip ""', '"hello" ""', '"" ellipsis' ],
invalid_values: [ "none", "auto", '"hello" inherit', 'inherit "hello"', 'clip initial', 'initial clip', 'initial inherit', 'inherit initial', 'inherit none']
},
"text-shadow": {

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

@ -1074,7 +1074,7 @@ nsTableFrame::GetChildLists(nsTArray<ChildList>* aLists) const
nsRect
nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) {
return mFrame->GetVisualOverflowRect() + ToReferenceFrame();
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
bool

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

@ -53,6 +53,7 @@
#include "xpcom-config.h"
#define MOZALLOC_HAVE_XMALLOC
#define MOZALLOC_HAVE_MALLOC_USABLE_SIZE
#if defined(MOZALLOC_EXPORT)
/* do nothing: it's been defined to __declspec(dllexport) by

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

@ -177,15 +177,12 @@ struct DebugOnly
T& operator->() { return value; }
bool operator<(const T& other) { return value < other; }
#else
DebugOnly() {}
DebugOnly(const T&) {}
DebugOnly& operator=(const T&) { return *this; }
void operator++(int) {}
void operator--(int) {}
bool operator<(const T&) { return false; }
#endif
/*

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

@ -437,10 +437,14 @@ pref("browser.ui.touch.weight.visited", 120); // percentage
// plugins
#if MOZ_PLATFORM_MAEMO == 6
pref("plugin.disable", false);
pref("dom.ipc.plugins.enabled", true);
#elifdef ANDROID
pref("plugin.disable", false);
pref("dom.ipc.plugins.enabled", false);
#else
pref("plugin.disable", true);
#endif
pref("dom.ipc.plugins.enabled", true);
#endif
// process priority
// higher values give content process less CPU time

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

@ -1384,28 +1384,57 @@
<xul:richlistbox anonid="child-items" class="remotetabs-list-children" flex="1" batch="25"/>
</content>
<implementation>
<field name="_syncTopics"><![CDATA[([
"browser:sync:setup:userabort",
"browser:sync:setup:networkerror",
"weave:service:login:finish",
"weave:service:login:error"
])]]>
</field>
<method name="open">
<body><![CDATA[
let self = this;
this.setAttribute("loading", "true");
this.removeAttribute("message");
if (Weave.Service.isLoggedIn) {
setTimeout(function() self._loadChildren(), 0);
} else {
// Wait until login or setup finishes before loading items.
let topics = [
"browser:sync:setup:userabort",
"browser:sync:setup:networkerror",
"weave:service:login:finish",
"weave:service:login:error"
];
function observe() {
topics.forEach(function(topic) Services.obs.removeObserver(observe, topic, false));
self._loadChildren();
}
topics.forEach(function(topic) Services.obs.addObserver(observe, topic, false));
}
// Try loading remote tabs straight away. It will
// simply return if sync is not setup.
setTimeout(function() {
if (self._loadChildren())
self.removeAttribute("loading");
}, 0);
this._syncObserver = function() {
this.removeAttribute("loading");
this._removeSyncObservers();
this._loadChildren();
}.bind(this);
// Wait for sync signals
this._syncTopics.forEach(function(topic) Services.obs.addObserver(self._syncObserver, topic, false));
]]></body>
</method>
<method name="close">
<body><![CDATA[
this.removeAttribute("message");
this.removeAttribute("loading");
// Stop listening to sync signals
this._removeSyncObservers();
]]></body>
</method>
<method name="_removeSyncObservers">
<body><![CDATA[
if (!this._syncObserver)
return;
let self = this;
this._syncTopics.forEach(function(topic) Services.obs.removeObserver(self._syncObserver, topic));
delete this._syncObserver;
]]></body>
</method>
@ -1417,22 +1446,23 @@
let engine = this._getWeaveEngine();
// Only load items if the tabs engine is ready. In case
// sync fails, WeaveGlue will show an error dialog. If sync
// succeeds but has no data to display, a message is presented
// in the panel (see "message" attribute).
if (engine) {
// Only load items if the tabs engine is ready
if (!engine)
return false;
// In case sync fails, WeaveGlue will show an error dialog
let items = this._getRemoteTabs(engine);
// If sync succeeds but has no data to display, a message
// is presented in the panel (see "message" attribute).
if (items.length) {
children.setItems(items.map(this.createItem));
} else {
let bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties");
this.setAttribute("message", bundle.GetStringFromName("sync.message.notabs"));
}
}
this.removeAttribute("loading");
return true;
]]></body>
</method>
@ -1447,7 +1477,7 @@
// Return null if the Weave isn't ready
if (document.getElementById("cmd_remoteTabs").getAttribute("disabled") == "true")
return null;
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED)
if (!Services.prefs.prefHasUserValue("services.sync.username")) {
return null;
return Weave.Engines.get("tabs");

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

@ -166,6 +166,7 @@
}
this.anchorNode = aAnchorNode;
this.position = aPosition;
let anchorRect = aAnchorNode.getBoundingClientRect();
let popupRect = new Rect(0,0,0,0);
@ -299,7 +300,7 @@
let arrowbox = document.getAnonymousElementByAttribute(self, "anonid", "arrowbox");
arrowbox.style.marginLeft = "0px";
arrowbox.style.marginTop = "0px";
self.anchorTo(self.anchorNode);
self.anchorTo(self.anchorNode, self.position);
break;
}
}

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

@ -1230,7 +1230,7 @@ var BrowserUI = {
AwesomeScreen.activePanel = HistoryList;
break;
case "cmd_remoteTabs":
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
if (!Services.prefs.prefHasUserValue("services.sync.username")) {
// We have to set activePanel before showing sync's dialog
// to make the sure the dialog stacking is correct.
AwesomeScreen.activePanel = RemoteTabsList;

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

@ -400,6 +400,7 @@ var Browser = {
messageManager.addMessageListener("Browser:CertException", this);
messageManager.addMessageListener("Browser:BlockedSite", this);
messageManager.addMessageListener("Browser:ErrorPage", this);
messageManager.addMessageListener("Browser:PluginClickToPlayClicked", this);
// Broadcast a UIReady message so add-ons know we are finished with startup
let event = document.createEvent("Events");
@ -498,6 +499,7 @@ var Browser = {
messageManager.removeMessageListener("Browser:CertException", this);
messageManager.removeMessageListener("Browser:BlockedSite", this);
messageManager.removeMessageListener("Browser:ErrorPage", this);
messageManager.removeMessageListener("Browser:PluginClickToPlayClicked", this);
var os = Services.obs;
os.removeObserver(XPInstallObserver, "addon-install-blocked");
@ -1275,6 +1277,31 @@ var Browser = {
case "Browser:ErrorPage":
this._handleErrorPage(aMessage);
break;
case "Browser:PluginClickToPlayClicked": {
// Save off session history
let parent = browser.parentNode;
let data = browser.__SS_data;
if (data.entries.length == 0)
return;
// Remove the browser from the DOM, effectively killing it's content
parent.removeChild(browser);
// Re-create the browser as non-remote, so plugins work
browser.setAttribute("remote", "false");
parent.appendChild(browser);
// Reload the content using session history
browser.__SS_data = data;
let json = {
uri: data.entries[data.index - 1].url,
flags: null,
entries: data.entries,
index: data.index
};
browser.messageManager.sendAsyncMessage("WebNavigation:LoadURI", json);
break;
}
}
}
};

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

@ -1570,3 +1570,53 @@ var SelectionHandler = {
};
SelectionHandler.init();
var PluginHandler = {
init: function() {
addEventListener("PluginClickToPlay", this, false);
},
addLinkClickCallback: function (linkNode, callbackName /*callbackArgs...*/) {
// XXX just doing (callback)(arg) was giving a same-origin error. bug?
let self = this;
let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
linkNode.addEventListener("click",
function(evt) {
if (!evt.isTrusted)
return;
evt.preventDefault();
if (callbackArgs.length == 0)
callbackArgs = [ evt ];
(self[callbackName]).apply(self, callbackArgs);
},
true);
linkNode.addEventListener("keydown",
function(evt) {
if (!evt.isTrusted)
return;
if (evt.keyCode == evt.DOM_VK_RETURN) {
evt.preventDefault();
if (callbackArgs.length == 0)
callbackArgs = [ evt ];
evt.preventDefault();
(self[callbackName]).apply(self, callbackArgs);
}
},
true);
},
handleEvent : function(event) {
if (event.type != "PluginClickToPlay")
return;
let plugin = event.target;
PluginHandler.addLinkClickCallback(plugin, "reloadToEnablePlugin");
},
reloadToEnablePlugin: function() {
sendAsyncMessage("Browser:PluginClickToPlayClicked", { });
}
};
PluginHandler.init();

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

@ -101,7 +101,7 @@ Sanitizer.prototype = {
get canClear()
{
return (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
return (Services.prefs.prefHasUserValue("services.sync.username"));
}
},

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

@ -53,7 +53,7 @@ let WeaveGlue = {
this.setupData = { account: "", password: "" , synckey: "", serverURL: "" };
// Generating keypairs is expensive on mobile, so disable it
if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
if (Services.prefs.prefHasUserValue("services.sync.username")) {
// Put the settings UI into a state of "connecting..." if we are going to auto-connect
this._elements.connect.firstChild.disabled = true;
this._elements.connect.setAttribute("title", this._bundle.GetStringFromName("connecting.label"));
@ -259,17 +259,11 @@ let WeaveGlue = {
tryConnect: function login() {
// If Sync is not configured, simply show the setup dialog
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
if (!Services.prefs.prefHasUserValue("services.sync.username")) {
this.open();
return;
}
// If user is already logged-in, try to connect straight away
if (Weave.Service.isLoggedIn) {
this.connect();
return;
}
// No setup data, do nothing
if (!this.setupData)
return;
@ -403,12 +397,12 @@ let WeaveGlue = {
let disconnect = this._elements.disconnect;
let sync = this._elements.sync;
let loggedIn = Weave.Service.isLoggedIn;
let isConfigured = Services.prefs.prefHasUserValue("services.sync.username");
connect.collapsed = loggedIn;
connected.collapsed = !loggedIn;
connect.collapsed = isConfigured;
connected.collapsed = !isConfigured;
if (!loggedIn) {
if (!isConfigured) {
connect.setAttribute("title", this._bundle.GetStringFromName("notconnected.label"));
connect.firstChild.disabled = false;
details.checked = false;
@ -449,7 +443,7 @@ let WeaveGlue = {
// Show what went wrong with login if necessary
if (aTopic == "weave:service:login:error") {
if (Weave.Status.login == "service.master_password_locked")
if (Weave.Status.login == Weave.MASTER_PASSWORD_LOCKED)
Weave.Service.logout();
else
connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));

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

@ -813,8 +813,14 @@ placeitem[ui="manage"] > .bookmark-manage textbox[anonid="uri"]:-moz-locale-dir(
#awesome-header .panel-row-button {
-moz-padding-end: 0px;
padding: @padding_normal@ !important;
border: none !important;
padding: @padding_large@ !important;
height: @touch_row@;
margin: 0px;
border: 0px;
}
#awesome-header .panel-row-button .toolbarbutton-text {
font-size: @font_xxtiny@ !important;
}
#awesome-header {
@ -1294,9 +1300,21 @@ pageaction > vbox {
/* Override richlistbox and richlistitem styles */
#context-header {
background-color: transparent;
border-bottom: @border_width_xlarge@ solid @color_divider_border@;
margin: @margin_large@ @margin_large@ 0px;
margin: 0px;
padding: 0px @padding_xlarge@;
min-height: @touch_row@
}
#context-header > label {
border-bottom: @border_width_xxlarge@ solid @color_divider_border@;
padding: @padding_xlarge@ @padding_large@;
color: @color_text_default@;
font-size: @font_snormal@;
margin: 0px;
}
#context-header > label[value=""] {
visibility: collapse;
}
#context-commands > scrollbox {
@ -1306,18 +1324,21 @@ pageaction > vbox {
.action-button,
.context-command {
-moz-box-align: center;
padding: 0px @padding_large@;
padding: 0px @padding_xlarge@;
border: none;
border-top: @border_width_tiny@ solid transparent;
font-size: @font_snormal@;
}
.action-button > label,
.context-command > label {
min-height: @touch_row@;
padding: 0px @padding_large@;
padding-top: -moz-calc(@touch_row@ / 2 - 0.75em);
-moz-box-align: center;
border-bottom: @border_width_tiny@ solid @color_button_border@;
-moz-box-flex: 1;
margin: 0px;
margin-bottom: -@border_width_tiny@;
}
@ -1406,17 +1427,12 @@ pageaction:not([image]) > hbox >.pageaction-image {
}
#share-title,
#bookmark-popup-title,
#context-hint {
#bookmark-popup-title {
color: @color_text_default@;
font-size: @font_small@;
padding: @padding_small@;
}
#context-hint[value=""] {
visibility: collapse;
}
#search-engines-list > .action-button > .button-box > .button-icon {
width: 32px;
height: 32px;
@ -1699,6 +1715,7 @@ setting[type="bool"]:hover:active .setting-input > checkbox[checked="true"] > .c
border-top: @border_width_tiny@ solid @color_button_border@;
border-bottom: none;
background-color: transparent;
font-size: @font_snormal@ !important;
}
#appmenu-popup-sitecommands {
@ -1708,7 +1725,7 @@ setting[type="bool"]:hover:active .setting-input > checkbox[checked="true"] > .c
}
#appmenu-popup-sitecommands > .appmenu-pageaction {
font-size: @font_tiny@;
font-size: @font_xxtiny@;
display: inline-block;
min-height: -moz-calc(1.5 * @touch_button_xlarge@) !important;
min-width: -moz-calc(1.5 * @touch_button_xlarge@) !important;

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

@ -623,17 +623,20 @@ dialog {
.prompt-message {
-moz-box-pack: center;
font-size: @font_snormal@;
padding-bottom: @padding_normal@;
min-height: 4em;
padding: @padding_normal@ @padding_large@;
min-height: @touch_row@;
}
.prompt-header {
border-bottom: @border_width_tiny@ solid @color_button_border@;
margin: @margin_normal@ @margin_large@ 0px !important;
margin: 0px @margin_large@ !important;
}
.prompt-title {
font-size: @font_snormal@;
min-height: @touch_row@;
padding: @padding_xlarge@ @padding_large@;
margin: 0px;
}
/* Authentication dialogs do not have a title */
@ -644,8 +647,8 @@ dialog {
.prompt-line {
background-color: transparent;
border-bottom: @border_width_xlarge@ solid @color_divider_border@;
height: @padding_normal@ !important;
border-bottom: @border_width_xxlarge@ solid @color_divider_border@;
height: @border_width_xxlarge@ !important;
}
.prompt-buttons {

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

@ -85,8 +85,6 @@ using namespace mozilla;
// ShortIdleTimeoutSeconds of idle time. Smaller pools use LongIdleTimeoutSeconds for a
// timeout period.
#define MAX_NON_PRIORITY_REQUESTS 150
#define HighThreadThreshold MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY
#define LongIdleTimeoutSeconds 300 // for threads 1 -> HighThreadThreshold
#define ShortIdleTimeoutSeconds 60 // for threads HighThreadThreshold+1 -> MAX_RESOLVER_THREADS

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

@ -71,8 +71,20 @@ class nsResolveHostCallback;
return n; \
}
#ifdef ANDROID
// See bug 687367 - pre gingerbread android has race conditions involving stdio.
// stdio is used as part of the getaddrinfo() implementation. In order to reduce
// that race window limit ourselves to 1 lookup at a time on android.
#define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 0
#define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 1
#define MAX_NON_PRIORITY_REQUESTS 0
#else
#define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 3
#define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
#define MAX_NON_PRIORITY_REQUESTS 150
#endif
#define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)

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