зеркало из https://github.com/mozilla/gecko-dev.git
Merge last green changeset from mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
b478778440
|
@ -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,<svg xmlns='http://www.w3.org/2000/svg'><g id='empty'/><mask id='mask' maskContentUnits='userSpaceOnUse'><rect width='50' height='50' fill='white'/></mask></svg>">
|
||||
]>
|
||||
<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: <use> targeting a fragment in a data URI
|
||||
</title>
|
||||
<rect fill="red" height="100%" width="100%"/>
|
||||
<use xlink:href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect id='target' height='100%' width='100%' fill='lime'/><rect height='100%' width='100%' fill='orange'/></svg>#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> </i><m>…</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> </i><m>…</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> </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> </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: <single value>, 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: <single value>, 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!
|
||||
|
||||
</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)
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче