This commit is contained in:
David Anderson 2012-02-21 15:08:22 -08:00
Родитель b518b4ed09 d31a9134b5
Коммит 7164dd290b
504 изменённых файлов: 14101 добавлений и 7332 удалений

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

@ -76,6 +76,7 @@ CPPSRCS = \
nsTextAccessible.cpp \
nsTextEquivUtils.cpp \
nsTextAttrs.cpp \
StyleInfo.cpp \
TextUpdater.cpp \
$(NULL)
@ -107,6 +108,7 @@ LOCAL_INCLUDES += \
-I$(srcdir)/../html \
-I$(srcdir)/../xul \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/style \
-I$(srcdir)/../../../layout/xul/base/src \
-I$(srcdir)/../xforms \
$(NULL)

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

@ -0,0 +1,112 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* 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 ***** */
#include "StyleInfo.h"
#include "mozilla/dom/Element.h"
#include "nsComputedDOMStyle.h"
using namespace mozilla;
using namespace mozilla::a11y;
StyleInfo::StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell) :
mElement(aElement)
{
mStyleContext =
nsComputedDOMStyle::GetStyleContextForElementNoFlush(aElement,
nsnull,
aPresShell);
}
void
StyleInfo::Display(nsAString& aValue)
{
aValue.Truncate();
AppendASCIItoUTF16(
nsCSSProps::ValueToKeyword(mStyleContext->GetStyleDisplay()->mDisplay,
nsCSSProps::kDisplayKTable), aValue);
}
void
StyleInfo::TextAlign(nsAString& aValue)
{
aValue.Truncate();
AppendASCIItoUTF16(
nsCSSProps::ValueToKeyword(mStyleContext->GetStyleText()->mTextAlign,
nsCSSProps::kTextAlignKTable), aValue);
}
void
StyleInfo::TextIndent(nsAString& aValue)
{
aValue.Truncate();
const nsStyleCoord& styleCoord =
mStyleContext->GetStyleText()->mTextIndent;
nscoord coordVal;
switch (styleCoord.GetUnit()) {
case eStyleUnit_Coord:
coordVal = styleCoord.GetCoordValue();
break;
case eStyleUnit_Percent:
{
nsIFrame* frame = mElement->GetPrimaryFrame();
nsIFrame* containerFrame = frame->GetContainingBlock();
nscoord percentageBase = containerFrame->GetContentRect().width;
coordVal = NSCoordSaturatingMultiply(percentageBase,
styleCoord.GetPercentValue());
break;
}
}
aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
aValue.AppendLiteral("px");
}
void
StyleInfo::Margin(css::Side aSide, nsAString& aValue)
{
aValue.Truncate();
nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide);
aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
aValue.AppendLiteral("px");
}

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

@ -1,4 +1,5 @@
/* vim: set sw=4 sts=4 et cin: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -12,21 +13,19 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OS/2 system font code in Thebes.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* John Fairhurst, <john_fairhurst@iname.com> } original developers of
* Henry Sobotka <sobotka@axess.com> } code taken from
* IBM Corp. } nsDeviceContextOS2
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* 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
@ -38,18 +37,41 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef _NS_SYSTEMFONTSOS2_H_
#define _NS_SYSTEMFONTSOS2_H_
#ifndef _mozilla_a11y_style_h_
#define _mozilla_a11y_style_h_
#include "gfxFont.h"
#include "nsDeviceContext.h"
#include "mozilla/gfx/Types.h"
#include "nsStyleContext.h"
class nsSystemFontsOS2
namespace mozilla {
namespace a11y {
class StyleInfo
{
public:
nsSystemFontsOS2();
nsresult GetSystemFont(nsSystemFontID aID, nsString* aFontName,
gfxFontStyle *aFontStyle) const;
StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell);
~StyleInfo() { };
void Display(nsAString& aValue);
void TextAlign(nsAString& aValue);
void TextIndent(nsAString& aValue);
void MarginLeft(nsAString& aValue) { Margin(css::eSideLeft, aValue); }
void MarginRight(nsAString& aValue) { Margin(css::eSideRight, aValue); }
void MarginTop(nsAString& aValue) { Margin(css::eSideTop, aValue); }
void MarginBottom(nsAString& aValue) { Margin(css::eSideBottom, aValue); }
private:
StyleInfo() MOZ_DELETE;
StyleInfo(const StyleInfo&) MOZ_DELETE;
StyleInfo& operator = (const StyleInfo&) MOZ_DELETE;
void Margin(css::Side aSide, nsAString& aValue);
dom::Element* mElement;
nsRefPtr<nsStyleContext> mStyleContext;
};
#endif /* _NS_SYSTEMFONTSOS2_H_ */
} // namespace a11y
} // namespace mozilla
#endif

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

@ -94,8 +94,8 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
skipEnd++;
}
PRInt32 strLen1 = oldLen - aSkipStart - skipEnd;
PRInt32 strLen2 = newLen - aSkipStart - skipEnd;
PRUint32 strLen1 = oldLen - aSkipStart - skipEnd;
PRUint32 strLen2 = newLen - aSkipStart - skipEnd;
const nsAString& str1 = Substring(aOldText, aSkipStart, strLen1);
const nsAString& str2 = Substring(aNewText, aSkipStart, strLen2);
@ -187,7 +187,7 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1,
PRInt32 colLen = colEnd + 1;
PRUint32* row = aEntries + rowIdx * colLen;
PRInt32 dist = row[colIdx]; // current Levenshtein distance
PRUint32 dist = row[colIdx]; // current Levenshtein distance
while (rowIdx && colIdx) { // stop when we can't move diagonally
if (aStr1[colIdx - 1] == aStr2[rowIdx - 1]) { // match
if (rowIdx < rowEnd) { // deal with any pending insertion

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

@ -44,19 +44,18 @@
#include "AccGroupInfo.h"
#include "AccIterator.h"
#include "nsAccUtils.h"
#include "nsDocAccessible.h"
#include "nsEventShell.h"
#include "nsAccEvent.h"
#include "nsAccessibleRelation.h"
#include "nsAccessibilityService.h"
#include "nsAccTreeWalker.h"
#include "nsIAccessibleRelation.h"
#include "nsEventShell.h"
#include "nsRootAccessible.h"
#include "nsTextEquivUtils.h"
#include "Relation.h"
#include "Role.h"
#include "States.h"
#include "StyleInfo.h"
#include "nsIDOMCSSValue.h"
#include "nsIDOMCSSPrimitiveValue.h"
@ -1442,49 +1441,40 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
startContent = parentDoc->FindContentForSubDocument(doc);
}
// Expose 'display' attribute.
if (!mContent->IsElement())
return NS_OK;
// CSS style based object attributes.
nsAutoString value;
nsresult rv = GetComputedStyleValue(EmptyString(),
NS_LITERAL_STRING("display"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
// Expose 'display' attribute.
styleInfo.Display(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
// Expose 'text-align' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-align"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
styleInfo.TextAlign(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
// Expose 'text-indent' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
styleInfo.TextIndent(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
// Expose 'margin-left' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-left"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
styleInfo.MarginLeft(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
// Expose 'margin-right' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-right"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
styleInfo.MarginRight(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
// Expose 'margin-top' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-top"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
styleInfo.MarginTop(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
// Expose 'margin-bottom' attribute.
rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-bottom"),
value);
if (NS_SUCCEEDED(rv))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
styleInfo.MarginBottom(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
// Expose draggable object attribute?
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);

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

@ -1494,28 +1494,24 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
* Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
*/
// Check for styled background color across the row
// Alternating background color is a common way
nsCOMPtr<nsIDOMNodeList> nodeList;
nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
tableElt->GetElementsByTagName(NS_LITERAL_STRING("tr"), getter_AddRefs(nodeList));
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
PRUint32 length;
nodeList->GetLength(&length);
nsAutoString color, lastRowColor;
for (PRUint32 rowCount = 0; rowCount < length; rowCount ++) {
nsCOMPtr<nsIDOMNode> rowNode;
nodeList->Item(rowCount, getter_AddRefs(rowNode));
nsCOMPtr<nsIContent> rowContent(do_QueryInterface(rowNode));
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), rowContent);
NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
lastRowColor = color;
styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"), color);
if (rowCount > 0 && false == lastRowColor.Equals(color)) {
RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
// Check for styled background color across rows (alternating background
// color is a common feature for data tables).
PRUint32 childCount = GetChildCount();
nsAutoString rowColor, prevRowColor;
for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible* child = GetChildAt(childIdx);
if (child->Role() == roles::ROW) {
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(),
child->GetContent());
if (styleDecl) {
prevRowColor = rowColor;
styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"),
rowColor);
if (childIdx > 0 && !prevRowColor.Equals(rowColor)) {
RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
}
}
}
}
@ -1525,30 +1521,17 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
RETURN_LAYOUT_ANSWER(false, ">= kMaxLayoutRows (20) and non-bordered");
}
// Check for very wide table
nsAutoString styledWidth;
GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("width"), styledWidth);
if (styledWidth.EqualsLiteral("100%")) {
RETURN_LAYOUT_ANSWER(true, "<=4 columns and 100% width");
}
if (styledWidth.Find(NS_LITERAL_STRING("px"))) { // Hardcoded in pixels
nsIFrame *tableFrame = GetFrame();
NS_ENSURE_TRUE(tableFrame , NS_ERROR_FAILURE);
nsSize tableSize = tableFrame->GetSize();
nsDocAccessible* docAccessible = Document();
NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
nsIFrame *docFrame = docAccessible->GetFrame();
NS_ENSURE_TRUE(docFrame , NS_ERROR_FAILURE);
nsSize docSize = docFrame->GetSize();
if (docSize.width > 0) {
PRInt32 percentageOfDocWidth = (100 * tableSize.width) / docSize.width;
if (percentageOfDocWidth > 95) {
// 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
// Probably for layout
RETURN_LAYOUT_ANSWER(true, "<=4 columns, width hardcoded in pixels and 95% of document width");
}
// Check for very wide table.
nsIFrame* documentFrame = Document()->GetFrame();
nsSize documentSize = documentFrame->GetSize();
if (documentSize.width > 0) {
nsSize tableSize = GetFrame()->GetSize();
PRInt32 percentageOfDocWidth = (100 * tableSize.width) / documentSize.width;
if (percentageOfDocWidth > 95) {
// 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
// Probably for layout
RETURN_LAYOUT_ANSWER(true,
"<= 4 columns, table width is 95% of document width");
}
}

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

@ -27,6 +27,26 @@ function testAbsentAttrs(aAccOrElmOrID, aAbsentAttrs)
testAttrsInternal(aAccOrElmOrID, {}, true, aAbsentAttrs);
}
/**
* Test CSS based object attributes.
*/
function testCSSAttrs(aID)
{
var node = document.getElementById(aID);
var computedStyle = document.defaultView.getComputedStyle(node, "");
var attrs = {
"display": computedStyle.display,
"text-align": computedStyle.textAlign,
"text-indent": computedStyle.textIndent,
"margin-left": computedStyle.marginLeft,
"margin-right": computedStyle.marginRight,
"margin-top": computedStyle.marginTop,
"margin-bottom": computedStyle.marginBottom
};
testAttrs(aID, attrs, true);
}
/**
* Test group object attributes (posinset, setsize and level) and
* nsIAccessible::groupPosition() method.

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

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_obj.html \
test_obj_css.html \
test_obj_css.xul \
test_obj_group.html \
test_obj_group.xul \
test_obj_group_tree.xul \

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

@ -18,36 +18,65 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
src="../attributes.js"></script>
<script type="application/javascript">
function testCSSAttrs(aID)
{
var node = document.getElementById(aID);
var computedStyle = document.defaultView.getComputedStyle(node, "");
var attrs = {
"display": computedStyle.display,
"text-align": computedStyle.textAlign,
"text-indent": computedStyle.textIndent,
"margin-left": computedStyle.marginLeft,
"margin-right": computedStyle.marginRight,
"margin-top": computedStyle.marginTop,
"margin-bottom": computedStyle.marginBottom
};
testAttrs(aID, attrs, true);
}
function doTest()
{
// CSS display
testCSSAttrs("display_block");
testCSSAttrs("display_inline");
testCSSAttrs("display_inline-block");
testCSSAttrs("display_list-item");
testCSSAttrs("display_table");
testCSSAttrs("display_inline-table");
testCSSAttrs("display_table-row-group");
testCSSAttrs("display_table-column");
testCSSAttrs("display_table-column-group");
testCSSAttrs("display_table-header-group");
testCSSAttrs("display_table-footer-group");
testCSSAttrs("display_table-row");
testCSSAttrs("display_table-cell");
testCSSAttrs("display_table-caption");
// CSS text-align
testCSSAttrs("text-align_left");
testCSSAttrs("text-align_right");
testCSSAttrs("text-align_center");
testCSSAttrs("text-align_justify");
testCSSAttrs("text-align_inherit");
// CSS text-indent
testCSSAttrs("text-indent_em");
testCSSAttrs("text-indent_ex");
testCSSAttrs("text-indent_in");
testCSSAttrs("text-indent_cm");
testCSSAttrs("text-indent_mm");
testCSSAttrs("text-indent_pt");
testCSSAttrs("text-indent_pc");
testCSSAttrs("text-indent_px");
testCSSAttrs("text-indent_percent");
testCSSAttrs("text-indent_inherit");
// CSS margin
testCSSAttrs("margin_em");
testCSSAttrs("margin_ex");
testCSSAttrs("margin_in");
testCSSAttrs("margin_cm");
testCSSAttrs("margin_mm");
testCSSAttrs("margin_pt");
testCSSAttrs("margin_pc");
testCSSAttrs("margin_px");
testCSSAttrs("margin_percent");
testCSSAttrs("margin_auto");
testCSSAttrs("margin_inherit");
testCSSAttrs("margin-left");
testCSSAttrs("margin-right");
testCSSAttrs("margin-top");
testCSSAttrs("margin-bottom");
// Elements
testCSSAttrs("span");
testCSSAttrs("div");
testCSSAttrs("p");
testCSSAttrs("p2");
testCSSAttrs("pml");
testCSSAttrs("pmr");
testCSSAttrs("pmt");
testCSSAttrs("pmb");
testCSSAttrs("input");
testCSSAttrs("table");
testCSSAttrs("tr");
@ -77,25 +106,85 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
title="Expose IA2 margin- object attributes">
Mozilla Bug 689540
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=714579"
title="Don't use GetComputedStyle for object attribute calculation">
Mozilla Bug 714579
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="display_block" role="img"
style="display: block;">display: block</div>
<div id="display_inline" role="img"
style="display: inline;">display: inline</div>
<div id="display_inline-block" role="img"
style="display: inline-block;">display: inline-block</div>
<div id="display_list-item" role="img"
style="display: list-item;">display: list-item</div>
<div id="display_table" role="img"
style="display: table;">display: table</div>
<div id="display_inline-table" role="img"
style="display: inline-table;">display: inline-table</div>
<div id="display_table-row-group" role="img"
style="display: table-row-group;">display: table-row-group</div>
<div id="display_table-column" role="img"
style="display: table-column;">display: table-column</div>
<div id="display_table-column-group" role="img"
style="display: table-column-group;">display: table-column-group</div>
<div id="display_table-header-group" role="img"
style="display: table-header-group;">display: table-header-group</div>
<div id="display_table-footer-group" role="img"
style="display: table-footer-group;">display: table-footer-group</div>
<div id="display_table-row" role="img"
style="display: table-row;">display: table-row</div>
<div id="display_table-cell" role="img"
style="display: table-cell;">display: table-cell</div>
<div id="display_table-caption" role="img"
style="display: table-caption;">display: table-caption</div>
<p id="text-align_left" style="text-align: left;">text-align: left</p>
<p id="text-align_right" style="text-align: right;">text-align: right</p>
<p id="text-align_center" style="text-align: center;">text-align: center</p>
<p id="text-align_justify" style="text-align: justify;">text-align: justify</p>
<p id="text-align_inherit" style="text-align: inherit;">text-align: inherit</p>
<p id="text-indent_em" style="text-indent: 0.5em;">text-indent: 0.5em</p>
<p id="text-indent_ex" style="text-indent: 1ex;">text-indent: 1ex</p>
<p id="text-indent_in" style="text-indent: 0.5in;">text-indent: 0.5in</p>
<p id="text-indent_cm" style="text-indent: 2cm;">text-indent: 2cm</p>
<p id="text-indent_mm" style="text-indent: 10mm;">text-indent: 10mm</p>
<p id="text-indent_pt" style="text-indent: 30pt;">text-indent: 30pt</p>
<p id="text-indent_pc" style="text-indent: 2pc;">text-indent: 2pc</p>
<p id="text-indent_px" style="text-indent: 5px;">text-indent: 5px</p>
<p id="text-indent_percent" style="text-indent: 10%;">text-indent: 10%</p>
<p id="text-indent_inherit" style="text-indent: inherit;">text-indent: inherit</p>
<p id="margin_em" style="margin: 0.5em;">margin: 0.5em</p>
<p id="margin_ex" style="margin: 1ex;">margin: 1ex</p>
<p id="margin_in" style="margin: 0.5in;">margin: 0.5in</p>
<p id="margin_cm" style="margin: 2cm;">margin: 2cm</p>
<p id="margin_mm" style="margin: 10mm;">margin: 10mm</p>
<p id="margin_pt" style="margin: 30pt;">margin: 30pt</p>
<p id="margin_pc" style="margin: 2pc;">margin: 2pc</p>
<p id="margin_px" style="margin: 5px;">margin: 5px</p>
<p id="margin_percent" style="margin: 10%;">margin: 10%</p>
<p id="margin_auto" style="margin: auto;">margin: auto</p>
<p id="margin_inherit" style="margin: inherit;">margin: inherit</p>
<p id="margin-left" style="margin-left: 11px;">margin-left: 11px</p>
<p id="margin-right" style="margin-right: 21px;">margin-right</p>
<p id="margin-top" style="margin-top: 31px;">margin-top: 31px</p>
<p id="margin-bottom" style="margin-bottom: 41px;">margin-bottom: 41px</p>
<span id="span" role="group">It's span</span>
<div id="div">It's div</div>
<p id="p">It's paragraph"</p>
<p id="p2" style="text-indent: 5px">It's another paragraph</p>
<p id="pml" style="margin-left : 11px;">It's a paragraph with left margin</p>
<p id="pmr" style="margin-right : 21px;">It's a paragraph with right margin</p>
<p id="pmt" style="margin-top : 31px;">It's a paragraph with top margin</p>
<p id="pmb" style="margin-bottom : 41px;">It's a paragraph with bottom margin</p>
<input id="input"/>
<table id="table">
<table id="table" style="margin: 2px; text-align: center; text-indent: 10%;">
<tr id="tr" role="group">
<td id="td">td</td>
</tr>

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

@ -0,0 +1,73 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessibility CSS-based Object Attributes Test.">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../events.js" />
<script type="application/javascript"
src="../attributes.js" />
<script type="application/javascript">
<![CDATA[
function doTest()
{
// CSS display
testCSSAttrs("display_mozbox");
testCSSAttrs("display_mozinlinebox");
testCSSAttrs("display_mozgrid");
testCSSAttrs("display_mozinlinegrid");
testCSSAttrs("display_mozgridgroup");
testCSSAttrs("display_mozgridline");
testCSSAttrs("display_mozstack");
testCSSAttrs("display_mozinlinestack");
testCSSAttrs("display_mozdeck");
testCSSAttrs("display_mozpopup");
testCSSAttrs("display_mozgroupbox");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=714579"
title="Don't use GetComputedStyle for object attribute calculation">
Mozilla Bug 714579
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox id="display_mozbox" style="display: -moz-box;" role="img"/>
<vbox id="display_mozinlinebox" style="display: -moz-inline-box;" role="img"/>
<vbox id="display_mozgrid" style="display: -moz-grid;" role="img"/>
<vbox id="display_mozinlinegrid" style="display: -moz-inline-grid;" role="img"/>
<vbox id="display_mozgridgroup" style="display: -moz-grid-group;" role="img"/>
<vbox id="display_mozgridline" style="display: -moz-grid-line;" role="img"/>
<vbox id="display_mozstack" style="display: -moz-stack;" role="img"/>
<vbox id="display_mozinlinestack" style="display: -moz-inline-stack;" role="img"/>
<vbox id="display_mozdeck" style="display: -moz-deck;" role="img"/>
<vbox id="display_mozpopup" style="display: -moz-popup;" role="img"/>
<vbox id="display_mozgroupbox" style="display: -moz-groupbox;" role="img"/>
</hbox>
</window>

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

@ -52,10 +52,17 @@ const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
////////////////////////////////////////////////////////////////////////////////
// OS detect
const MAC = (navigator.platform.indexOf("Mac") != -1)? true : false;
const LINUX = (navigator.platform.indexOf("Linux") != -1)? true : false;
const SOLARIS = (navigator.platform.indexOf("SunOS") != -1)? true : false;
const WIN = (navigator.platform.indexOf("Win") != -1)? true : false;
const MAC = (navigator.platform.indexOf("Mac") != -1);
const LINUX = (navigator.platform.indexOf("Linux") != -1);
const SOLARIS = (navigator.platform.indexOf("SunOS") != -1);
const WIN = (navigator.platform.indexOf("Win") != -1);
////////////////////////////////////////////////////////////////////////////////
// Application detect
// Firefox is assumed by default.
const SEAMONKEY = navigator.userAgent.match(/ SeaMonkey\//);
////////////////////////////////////////////////////////////////////////////////
// Accessible general

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

@ -382,6 +382,12 @@
var gInitQueue = null;
function initTests()
{
if (SEAMONKEY) {
todo(false, "Skipping this test on SeaMonkey ftb. (Bug 718237)");
SimpleTest.finish();
return;
}
// register 'test-a11y-search' autocomplete search
initAutoComplete([ "hello", "hi" ],
[ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);

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

@ -52,7 +52,7 @@
};
// SeaMonkey and Firefox tabbrowser UIs differ.
if ("restoreTab" in tabBrowser) {
if (SEAMONKEY) {
SimpleTest.ok(true, "Testing SeaMonkey tabbrowser UI.");
tabsAccTree.children.splice(0, 0,

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

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_ariadialog.html \
test_colorpicker.xul \
test_cssoverflow.html \
test_contextmenu.xul \
test_doc.html \
test_gencontent.html \

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

@ -0,0 +1,141 @@
<html>
<head>
<title>Testing HTML scrollable frames (css overflow style)</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
////////////////////////////////////////////////////////////////////////////
/**
* Change scroll range to not empty size and inserts a child into container
* to trigger tree update of the container. Prior to bug 677154 not empty
* size resulted to accessible creation for scroll area, container tree
* update picked up that accessible unattaching scroll area accessible
* subtree.
*/
function changeScrollRange(aContainerID, aScrollAreaID)
{
this.containerNode = getNode(aContainerID);
this.container = getAccessible(this.containerNode);
this.scrollAreaNode = getNode(aScrollAreaID);
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.container)
];
this.invoke = function changeScrollRange_invoke()
{
this.scrollAreaNode.style.width = "20px";
this.containerNode.appendChild(document.createElement("input"));
}
this.finalCheck = function changeScrollRange_finalCheck()
{
var accTree =
{ SECTION: [ // container
{ SECTION: [ // scroll area
{ ENTRY: [] } // child content
] },
{ ENTRY: [] } // inserted input
] };
testAccessibleTree(this.container, accTree);
}
this.getID = function changeScrollRange_getID()
{
return "change scroll range for " + prettyName(aScrollAreaID);
}
}
/**
* Change scrollbar styles from hidden to auto. That makes us to create an
* accessible for scroll area.
*/
function changeScrollbarStyles(aContainerID, aScrollAreaID)
{
this.container = getAccessible(aContainerID);
this.scrollAreaNode = getNode(aScrollAreaID);
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getAccessible, this.scrollAreaNode),
new invokerChecker(EVENT_REORDER, this.container)
];
this.invoke = function changeScrollbarStyles_invoke()
{
var accTree =
{ SECTION: [] };
testAccessibleTree(this.container, accTree);
this.scrollAreaNode.style.overflow = "auto";
}
this.finalCheck = function changeScrollbarStyles_finalCheck()
{
var accTree =
{ SECTION: [ // container
{ SECTION: [] } // scroll area
] };
testAccessibleTree(this.container, accTree);
}
this.getID = function changeScrollbarStyles_getID()
{
return "change scrollbar styles " + prettyName(aScrollAreaID);
}
}
////////////////////////////////////////////////////////////////////////////
// Do tests
////////////////////////////////////////////////////////////////////////////
var gQueue = null;
//gA11yEventDumpID = "eventdump"; // debug stuff
//gA11yEventDumpToConsole = true;
function doTests()
{
gQueue = new eventQueue();
gQueue.push(new changeScrollRange("container", "scrollarea"));
gQueue.push(new changeScrollbarStyles("container2", "scrollarea2"));
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=677154"
title="Detached document accessibility tree">
Mozilla Bug 677154</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="eventdump"></div>
<div id="container"><div id="scrollarea" style="overflow:auto;"><input></div></div>
<div id="container2"><div id="scrollarea2" style="overflow:hidden;"></div></div>
</body>
</html>

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

@ -46,7 +46,7 @@ pref("browser.homescreenURL", "file:///data/local/homescreen.html,file:///system
#endif
// URL for the dialer application.
pref("dom.telephony.app.phone.url", "http://localhost:6666/apps/dialer/dialer.html");
pref("dom.telephony.app.phone.url", "http://localhost:7777/data/local/apps/dialer/dialer.html");
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
pref("browser.viewport.scaleRatio", -1);
@ -404,11 +404,11 @@ pref("browser.link.open_newwindow.restriction", 0);
// Enable browser frame
pref("dom.mozBrowserFramesEnabled", true);
pref("dom.mozBrowserFramesWhitelist", "http://localhost:6666");
pref("dom.mozBrowserFramesWhitelist", "http://localhost:7777");
// Temporary permission hack for WebSMS
pref("dom.sms.enabled", true);
pref("dom.sms.whitelist", "file://,http://localhost:6666");
pref("dom.sms.whitelist", "file://,http://localhost:7777");
// Ignore X-Frame-Options headers.
pref("b2g.ignoreXFrameOptions", true);
@ -426,6 +426,10 @@ pref("media.realtime_decoder.enabled", true);
// by bug 710563.
pref("layout.frame_rate.precise", true);
// Temporary remote js console hack
pref("b2g.remote-js.enabled", true);
pref("b2g.remote-js.port", 9999);
// Screen timeout in minutes
pref("power.screen.timeout", 60);

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

@ -8,6 +8,7 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const CC = Components.Constructor;
const Cr = Components.results;
const LocalFile = CC('@mozilla.org/file/local;1',
'nsILocalFile',
@ -25,24 +26,16 @@ XPCOMUtils.defineLazyGetter(Services, 'ss', function() {
return Cc['@mozilla.org/content/style-sheet-service;1']
.getService(Ci.nsIStyleSheetService);
});
XPCOMUtils.defineLazyGetter(Services, 'idle', function() {
return Cc['@mozilla.org/widget/idleservice;1']
.getService(Ci.nsIIdleService);
});
// In order to use http:// scheme instead of file:// scheme
// (that is much more restricted) the following code kick-off
// a local http server listening on http://127.0.0.1:7777 and
// http://localhost:7777.
function startupHttpd(baseDir, port) {
const httpdURL = 'chrome://browser/content/httpd.js';
let httpd = {};
Services.scriptloader.loadSubScript(httpdURL, httpd);
let server = new httpd.nsHttpServer();
server.registerDirectory('/', new LocalFile(baseDir));
server.registerContentType('appcache', 'text/cache-manifest');
server.start(port);
}
XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function(){
return Cc['@mozilla.org/focus-managr;1']
.getService(Ci.nsFocusManager);
});
// FIXME Bug 707625
// until we have a proper security model, add some rights to
@ -62,7 +55,6 @@ function addPermissions(urls) {
});
}
var shell = {
// FIXME/bug 678695: this should be a system setting
preferredScreenBrightness: 1.0,
@ -105,6 +97,7 @@ var shell = {
window.addEventListener('keypress', this);
window.addEventListener('MozApplicationManifest', this);
window.addEventListener("AppCommand", this);
window.addEventListener('mozfullscreenchange', this);
this.contentBrowser.addEventListener('load', this, true);
try {
@ -112,17 +105,7 @@ var shell = {
let fileScheme = 'file://';
if (homeURL.substring(0, fileScheme.length) == fileScheme) {
homeURL = homeURL.replace(fileScheme, '');
let baseDir = homeURL.split('/');
baseDir.pop();
baseDir = baseDir.join('/');
const SERVER_PORT = 6666;
startupHttpd(baseDir, SERVER_PORT);
let baseHost = 'http://localhost';
homeURL = homeURL.replace(baseDir, baseHost + ':' + SERVER_PORT);
homeURL = 'http://localhost:7777' + homeURL.replace(fileScheme, '');
}
addPermissions([homeURL]);
} catch (e) {
@ -130,12 +113,12 @@ var shell = {
return alert(msg);
}
// Load webapi+apps.js as a frame script
// Load webapi.js as a frame script
let frameScriptUrl = 'chrome://browser/content/webapi.js';
try {
messageManager.loadFrameScript(frameScriptUrl, true);
} catch (e) {
dump('Error when loading ' + frameScriptUrl + ' as a frame script: ' + e + '\n');
dump('Error loading ' + frameScriptUrl + ' as a frame script: ' + e + '\n');
}
let browser = this.contentBrowser;
@ -243,6 +226,14 @@ var shell = {
break;
}
break;
case 'mozfullscreenchange':
// When the screen goes fullscreen make sure to set the focus to the
// main window so noboby can prevent the ESC key to get out fullscreen
// mode
if (document.mozFullScreen)
Services.fm.focusedWindow = window;
break;
case 'load':
this.contentBrowser.removeEventListener('load', this, true);
this.turnScreenOn();
@ -363,3 +354,50 @@ Services.obs.addObserver(function onConsoleAPILogEvent(subject, topic, data) {
" in " + (message.functionName || "anonymous") + ": ";
Services.console.logStringMessage(prefix + Array.join(message.arguments, " "));
}, "console-api-log-event", false);
(function Repl() {
if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
return;
}
const prompt = 'JS> ';
let output;
let reader = {
onInputStreamReady : function repl_readInput(input) {
let sin = Cc['@mozilla.org/scriptableinputstream;1']
.createInstance(Ci.nsIScriptableInputStream);
sin.init(input);
try {
let val = eval(sin.read(sin.available()));
let ret = (typeof val === 'undefined') ? 'undefined\n' : val + '\n';
output.write(ret, ret.length);
// TODO: check if socket has been closed
} catch (e) {
if (e.result === Cr.NS_BASE_STREAM_CLOSED ||
(typeof e === 'object' && e.result === Cr.NS_BASE_STREAM_CLOSED)) {
return;
}
let message = (typeof e === 'object') ? e.message + '\n' : e + '\n';
output.write(message, message.length);
}
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
}
}
let listener = {
onSocketAccepted: function repl_acceptConnection(serverSocket, clientSocket) {
dump('Accepted connection on ' + clientSocket.host + '\n');
let input = clientSocket.openInputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
output = clientSocket.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
}
}
let serverPort = Services.prefs.getIntPref('b2g.remote-js.port');
let serverSocket = Cc['@mozilla.org/network/server-socket;1']
.createInstance(Ci.nsIServerSocket);
serverSocket.init(serverPort, true, -1);
dump('Opened socket on ' + serverSocket.port + '\n');
serverSocket.asyncListen(listener);
})();

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

@ -177,19 +177,22 @@ const ContentPanning = {
}
},
position: {
origin: new Point(0, 0),
current: new Point(0 , 0)
},
position: new Point(0 , 0),
onTouchStart: function cp_onTouchStart(evt) {
this.dragging = true;
KineticPanning.stop();
// If there is a pan animation running (from a previous pan gesture) and
// the user touch back the screen, stop this animation immediatly and
// prevent the possible click action.
if (KineticPanning.active) {
KineticPanning.stop();
this.preventNextClick = true;
}
this.scrollCallback = this.getPannable(evt.originalTarget);
this.position.origin.set(evt.screenX, evt.screenY);
this.position.current.set(evt.screenX, evt.screenY);
KineticPanning.record(new Point(0, 0));
this.position.set(evt.screenX, evt.screenY);
KineticPanning.record(new Point(0, 0), evt.timeStamp);
},
onTouchEnd: function cp_onTouchEnd(evt) {
@ -197,26 +200,29 @@ const ContentPanning = {
return;
this.dragging = false;
if (this.isPan()) {
if (evt.detail) // The event will generate a click
evt.target.addEventListener('click', this, true);
this.onTouchMove(evt);
let pan = KineticPanning.isPan();
let click = evt.detail;
if (click && (pan || this.preventNextClick))
evt.target.addEventListener('click', this, true);
this.preventNextClick = false;
if (pan)
KineticPanning.start(this);
}
},
onTouchMove: function cp_onTouchMove(evt) {
if (!this.dragging || !this.scrollCallback)
return;
let current = this.position.current;
let current = this.position;
let delta = new Point(evt.screenX - current.x, evt.screenY - current.y);
current.set(evt.screenX, evt.screenY);
if (this.isPan()) {
KineticPanning.record(delta);
this.scrollCallback(delta.scale(-1));
}
KineticPanning.record(delta, evt.timeStamp);
this.scrollCallback(delta.scale(-1));
},
@ -232,24 +238,11 @@ const ContentPanning = {
this.scrollCallback = null;
},
isPan: function cp_isPan() {
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.displayDPI;
let threshold = Services.prefs.getIntPref('ui.dragThresholdX') / 240 * dpi;
let deltaX = this.position.origin.x - this.position.current.x;
let deltaY = this.position.origin.y - this.position.current.y;
return (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold);
},
getPannable: function cp_getPannable(node) {
if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
return null;
let content = node.ownerDocument.defaultView;
while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
let style = content.getComputedStyle(node, null);
@ -299,7 +292,7 @@ const kMinVelocity = 0.4;
const kMaxVelocity = 6;
// Constants that affect the "friction" of the scroll pane.
const kExponentialC = 1400;
const kExponentialC = 1000;
const kPolynomialC = 100 / 1000000;
// How often do we change the position of the scroll pane?
@ -307,17 +300,25 @@ const kPolynomialC = 100 / 1000000;
// Too little and panning will be choppy. In milliseconds.
const kUpdateInterval = 16;
// The numbers of momentums to use for calculating the velocity of the pan.
// Those are taken from the end of the action
const kSamples = 5;
const KineticPanning = {
_position: new Point(0, 0),
_velocity: new Point(0, 0),
_acceleration: new Point(0, 0),
get active() {
return this.target !== null;
},
_target: null,
start: function kp_start(target) {
this.target = target;
// Calculate the initial velocity of the movement based on user input
let momentums = this.momentums;
let momentums = this.momentums.slice(-kSamples);
let distance = new Point(0, 0);
momentums.forEach(function(momentum) {
@ -338,6 +339,7 @@ const KineticPanning = {
let velocity = this._velocity;
velocity.set(Math.abs(velocityX) < kMinVelocity ? 0 : velocityX,
Math.abs(velocityY) < kMinVelocity ? 0 : velocityY);
this.momentums = [];
// Set acceleration vector to opposite signs of velocity
function sign(x) {
@ -358,20 +360,32 @@ const KineticPanning = {
if (!this.target)
return;
this.momentums.splice(0);
this.momentums = [];
this.target.onKineticEnd();
this.target = null;
},
momentums: [],
record: function kp_record(delta) {
// If the panning direction has changed, stop the current activity.
if (this.target && ((delta.x * this._velocity.x < 0) ||
(delta.y * this._velocity.y < 0)))
this.stop();
record: function kp_record(delta, timestamp) {
this.momentums.push({ 'time': timestamp, 'dx' : delta.x, 'dy' : delta.y });
},
this.momentums.push({ 'time': Date.now(), 'dx' : delta.x, 'dy' : delta.y });
isPan: function cp_isPan() {
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.displayDPI;
let threshold = Services.prefs.getIntPref('ui.dragThresholdX') / 240 * dpi;
let deltaX = 0;
let deltaY = 0;
let start = this.momentums[0].time;
return this.momentums.slice(1).some(function(momentum) {
deltaX += momentum.dx;
deltaY += momentum.dy;
return (Math.abs(deltaX) > threshold) || (Math.abs(deltaY) > threshold);
});
},
_startAnimation: function kp_startAnimation() {

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

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1328822681000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1329176667000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -27,8 +27,12 @@
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
<emItem blockID="i65" id="activity@facebook.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i66" id="youtubeer@youtuber.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i54" id="applebeegifts@mozilla.doslash.org">
@ -122,8 +126,11 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i56" id="flash@adobe.com">
<versionRange minVersion="0" maxVersion="*">
<emItem blockID="i23" id="firefox@bandoo.com">
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i55" id="youtube@youtube7.com">
@ -178,11 +185,8 @@
<versionRange minVersion="2.2" maxVersion="2.2">
</versionRange>
</emItem>
<emItem blockID="i23" id="firefox@bandoo.com">
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
<emItem blockID="i56" id="flash@adobe.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
@ -192,6 +196,10 @@
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
</versionRange>
</emItem>
<emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
<versionRange minVersion="2.0" maxVersion="2.0">
</versionRange>

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

@ -282,6 +282,7 @@ pref("browser.urlbar.doubleClickSelectsAll", true);
pref("browser.urlbar.doubleClickSelectsAll", false);
#endif
pref("browser.urlbar.autoFill", false);
pref("browser.urlbar.autoFill.typed", true);
// 0: Match anywhere (e.g., middle of words)
// 1: Match on word boundaries and then try matching anywhere
// 2: Match only on word boundaries (e.g., after / or .)

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

@ -9053,7 +9053,14 @@ XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() {
var StyleEditor = {
prefEnabledName: "devtools.styleeditor.enabled",
openChrome: function SE_openChrome()
/**
* Opens the style editor. If the UI is already open, it will be focused.
*
* @param {CSSStyleSheet} [aSelectedStyleSheet] default Stylesheet.
* @param {Number} [aLine] Line to which the caret should be moved (one-indexed).
* @param {Number} [aCol] Column to which the caret should be moved (one-indexed).
*/
openChrome: function SE_openChrome(aSelectedStyleSheet, aLine, aCol)
{
const CHROME_URL = "chrome://browser/content/styleeditor.xul";
const CHROME_WINDOW_TYPE = "Tools:StyleEditor";
@ -9067,14 +9074,23 @@ var StyleEditor = {
while (enumerator.hasMoreElements()) {
var win = enumerator.getNext();
if (win.styleEditorChrome.contentWindowID == contentWindowID) {
if (aSelectedStyleSheet) {
win.styleEditorChrome.selectStyleSheet(aSelectedStyleSheet, aLine, aCol);
}
win.focus();
return win;
}
}
let args = {
contentWindow: contentWindow,
selectedStyleSheet: aSelectedStyleSheet,
line: aLine,
col: aCol
};
args.wrappedJSObject = args;
let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
CHROME_WINDOW_FLAGS,
contentWindow);
CHROME_WINDOW_FLAGS, args);
chromeWindow.focus();
return chromeWindow;
}

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

@ -1371,7 +1371,8 @@
// pretend the user typed this so it'll be available till
// the document successfully loads
b.userTypedValue = aURI;
if (!isBlankPageURL(aURI))
b.userTypedValue = aURI;
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
if (aAllowThirdPartyFixup)
@ -1563,15 +1564,26 @@
<parameter name="aCloseWindowFastpath"/>
<body>
<![CDATA[
if (aTab.closing || this._windowIsClosing)
if (aTab.closing ||
aTab._pendingPermitUnload ||
this._windowIsClosing)
return false;
var browser = this.getBrowserForTab(aTab);
if (!aTabWillBeMoved) {
let ds = browser.docShell;
if (ds && ds.contentViewer && !ds.contentViewer.permitUnload())
return false;
if (ds && ds.contentViewer) {
// We need to block while calling permitUnload() because it
// processes the event queue and may lead to another removeTab()
// call before permitUnload() even returned.
aTab._pendingPermitUnload = true;
let permitUnload = ds.contentViewer.permitUnload();
delete aTab._pendingPermitUnload;
if (!permitUnload)
return false;
}
}
var closeWindow = false;
@ -3539,12 +3551,14 @@
// it triggers will correctly update our URL bar.
this.tabbrowser.selectedTab = newTab;
} else {
let url = browserDragAndDrop.drop(event, { });
// Pass true to disallow dropping javascript: or data: urls
let url;
try {
url = browserDragAndDrop.drop(event, { }, true);
} catch (ex) {}
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
// Also disallow dropping javascript: or data: urls--bail out
if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
/^\s*(javascript|data):/.test(url))
if (!url || url.indexOf(" ") != -1)
return;
let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");

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

@ -268,6 +268,7 @@ _BROWSER_FILES = \
browser_aboutSyncProgress.js \
browser_middleMouse_inherit.js \
redirect_bug623155.sjs \
browser_tabDrop.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))

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

@ -26,6 +26,7 @@ function test() {
// Now trigger the invalid URI test
executeSoon(function () {
info("Dialog closed? " + domwindow.closed + "\n");
let consoleListener = {
observe: function (m) {
info("m: " + m + "\n");
@ -44,6 +45,14 @@ function test() {
// The drop handler throws an exception when dragging URIs that inherit
// principal, e.g. javascript:
expectUncaughtException();
let originalHandler = homeButtonObserver.onDrop;
homeButtonObserver.onDrop = function (aEvent) {
info("homeButtonObserver.onDrop called");
originalHandler(aEvent);
};
registerCleanupFunction(function () {
homeButtonObserver.onDrop = originalHandler;
});
chromeUtils.synthesizeDrop(homeButton, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window, EventUtils);
})
});

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

@ -0,0 +1,71 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let newTab = gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
registerCleanupFunction(function () {
gBrowser.removeTab(newTab);
});
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
let chromeUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
let tabContainer = gBrowser.tabContainer;
var receivedDropCount = 0;
function dropListener() {
receivedDropCount++;
if (receivedDropCount == triggeredDropCount) {
is(openedTabs, validDropCount, "correct number of tabs were opened");
executeSoon(finish);
}
}
tabContainer.addEventListener("drop", dropListener, false);
registerCleanupFunction(function () {
tabContainer.removeEventListener("drop", dropListener, false);
});
var openedTabs = 0;
function tabOpenListener(e) {
openedTabs++;
let tab = e.target;
executeSoon(function () {
gBrowser.removeTab(tab);
});
}
tabContainer.addEventListener("TabOpen", tabOpenListener, false);
registerCleanupFunction(function () {
tabContainer.removeEventListener("TabOpen", tabOpenListener, false);
});
var triggeredDropCount = 0;
var validDropCount = 0;
function drop(text, valid) {
triggeredDropCount++;
if (valid)
validDropCount++;
executeSoon(function () {
// A drop type of "link" onto an existing tab would normally trigger a
// load in that same tab, but tabbrowser code in _getDragTargetTab treats
// drops on the outer edges of a tab differently (loading a new tab
// instead). The events created by synthesizeDrop have all of their
// coordinates set to 0 (screenX/screenY), so they're treated as drops
// on the outer edge of the tab, thus they open new tabs.
chromeUtils.synthesizeDrop(newTab, newTab, [[{type: "text/plain", data: text}]], "link", window, EventUtils);
});
}
// Begin and end with valid drops to make sure we wait for all drops before
// ending the test
drop("mochi.test/first", true);
drop("javascript:'bad'");
drop("jAvascript:'bad'");
drop("space bad");
drop("mochi.test/second", true);
drop("data:text/html,bad");
drop("mochi.test/third", true);
}

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

@ -52,7 +52,6 @@ const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
const nsIDOMChromeWindow = Components.interfaces.nsIDOMChromeWindow;
const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
const nsIFileURL = Components.interfaces.nsIFileURL;
const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
const nsINetUtil = Components.interfaces.nsINetUtil;
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
@ -65,13 +64,12 @@ const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
const nsIXULAppInfo = Components.interfaces.nsIXULAppInfo;
const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
const URI_INHERITS_SECURITY_CONTEXT = Components.interfaces.nsIHttpProtocolHandler
.URI_INHERITS_SECURITY_CONTEXT;
function shouldLoadURI(aURI) {
@ -137,16 +135,14 @@ function needHomepageOverride(prefb) {
if (savedmstone == "ignore")
return OVERRIDE_NONE;
var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
.getService(nsIHttpProtocolHandler).misc;
var mstone = Services.appinfo.platformVersion;
var savedBuildID = null;
try {
savedBuildID = prefb.getCharPref("browser.startup.homepage_override.buildID");
} catch (e) {}
var buildID = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(nsIXULAppInfo).platformBuildID;
var buildID = Services.appinfo.platformBuildID;
if (mstone != savedmstone) {
// Bug 462254. Previous releases had a default pref to suppress the EULA

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

@ -72,6 +72,7 @@ _BROWSER_TEST_FILES = \
browser_dbg_pause-resume.js \
browser_dbg_update-editor-mode.js \
browser_dbg_select-line.js \
browser_dbg_clean-exit.js \
head.js \
$(NULL)

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

@ -0,0 +1,42 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Test that closing a tab with the debugger in a paused state exits cleanly.
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
const DEBUGGER_TAB_URL = "http://example.com/browser/browser/devtools/" +
"debugger/test/" +
"browser_dbg_debuggerstatement.html";
function test() {
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.debuggerWindow;
testCleanExit();
});
}
function testCleanExit() {
gPane.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
is(gDebugger.StackFrames.activeThread.paused, true,
"Should be paused after the debugger statement.");
gPane._client.addOneTimeListener("tabDetached", function () {
finish();
});
removeTab(gTab);
}}, 0);
});
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
}

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

@ -763,6 +763,9 @@ InspectorUI.prototype = {
this.boundRuleViewChanged = this.ruleViewChanged.bind(this);
this.ruleView.element.addEventListener("CssRuleViewChanged",
this.boundRuleViewChanged);
this.cssRuleViewBoundCSSLinkClicked = this.ruleViewCSSLinkClicked.bind(this);
this.ruleView.element.addEventListener("CssRuleViewCSSLinkClicked",
this.cssRuleViewBoundCSSLinkClicked);
doc.documentElement.appendChild(this.ruleView.element);
this.ruleView.highlight(this.selection);
@ -800,6 +803,30 @@ InspectorUI.prototype = {
this.nodeChanged(this.ruleViewObject);
},
/**
* When a css link is clicked this method is called in order to either:
* 1. Open the link in view source (for element style attributes)
* 2. Open the link in the style editor
*
* @param aEvent The event containing the style rule to act on
*/
ruleViewCSSLinkClicked: function(aEvent)
{
if (!this.chromeWin) {
return;
}
let rule = aEvent.detail.rule;
let styleSheet = rule.sheet;
if (styleSheet) {
this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
} else {
let href = rule.elementStyle.element.ownerDocument.location.href;
this.chromeWin.openUILinkIn("view-source:" + href, "window");
}
},
/**
* Destroy the rule view.
*/
@ -811,6 +838,8 @@ InspectorUI.prototype = {
if (this.ruleView) {
this.ruleView.element.removeEventListener("CssRuleViewChanged",
this.boundRuleViewChanged);
this.ruleView.element.removeEventListener("CssRuleViewCSSLinkClicked",
this.cssRuleViewBoundCSSLinkClicked);
delete boundRuleViewChanged;
this.ruleView.clear();
delete this.ruleView;

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

@ -78,6 +78,9 @@ const ORION_EVENTS = {
Selection: "Selection",
Focus: "Focus",
Blur: "Blur",
MouseOver: "MouseOver",
MouseOut: "MouseOut",
MouseMove: "MouseMove",
};
/**

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

@ -161,6 +161,30 @@ SourceEditor.EVENTS = {
* The blur event is fired when the editor goes out of focus.
*/
BLUR: "Blur",
/**
* The MouseMove event is sent when the user moves the mouse over a line
* annotation. The event object properties:
* - event - the DOM mousemove event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_MOVE: "MouseMove",
/**
* The MouseOver event is sent when the mouse pointer enters a line
* annotation. The event object properties:
* - event - the DOM mouseover event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_OVER: "MouseOver",
/**
* This MouseOut event is sent when the mouse pointer exits a line
* annotation. The event object properties:
* - event - the DOM mouseout event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_OUT: "MouseOut",
};
/**

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

@ -55,6 +55,7 @@ _BROWSER_TEST_FILES = \
browser_bug687160_line_api.js \
browser_bug650345_find.js \
browser_bug703692_focus_blur.js \
browser_bug725388_mouse_events.js \
head.js \
libs:: $(_BROWSER_TEST_FILES)

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

@ -0,0 +1,97 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let tempScope = {};
Cu.import("resource:///modules/source-editor.jsm", tempScope);
let SourceEditor = tempScope.SourceEditor;
let testWin;
let editor;
function test()
{
waitForExplicitFinish();
const windowUrl = "data:text/xml,<?xml version='1.0'?>" +
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
" title='Test for bug 725388' width='600' height='500'><hbox flex='1'/></window>";
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
testWin.addEventListener("load", function onWindowLoad() {
testWin.removeEventListener("load", onWindowLoad, false);
waitForFocus(initEditor, testWin);
}, false);
}
function initEditor()
{
let hbox = testWin.document.querySelector("hbox");
editor = new SourceEditor();
editor.init(hbox, {}, editorLoaded);
}
function editorLoaded()
{
let text = "BrowserBug - 725388";
editor.setText(text);
let target = editor.editorElement;
let targetWin = target.ownerDocument.defaultView;
let mMoveHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
is(aEvent.event.type, "mousemove", "MouseMove event fired.");
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
waitForFocus(function() {
EventUtils.synthesizeMouse(target, 10, 10, {type: "mouseover"},
targetWin);
});
};
let mOverHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
is(aEvent.event.type, "mouseover", "MouseOver event fired.");
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
waitForFocus(function() {
EventUtils.synthesizeMouse(target, -10, -10, {type: "mouseout"},
targetWin);
}, targetWin);
};
let mOutHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
is(aEvent.event.type, "mouseout", "MouseOut event fired.");
executeSoon(testEnd);
};
editor.addEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
editor.focus();
waitForFocus(function() {
EventUtils.synthesizeMouse(target, 1, 1, {type: "mousemove"},
targetWin);
}, targetWin);
}
function testEnd()
{
if (editor) {
editor.destroy();
}
if (testWin) {
testWin.close();
}
testWin = editor = null;
waitForFocus(finish, window);
}

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

@ -146,7 +146,7 @@ StyleEditor.prototype = {
*/
get styleSheet()
{
assert(this._styleSheet, "StyleSheet must be loaded first.")
assert(this._styleSheet, "StyleSheet must be loaded first.");
return this._styleSheet;
},
@ -921,9 +921,11 @@ StyleEditor.prototype = {
aArgs.unshift(this);
}
// copy the list of listeners to allow adding/removing listeners in handlers
let listeners = this._actionListeners.concat();
// trigger all listeners that have this action handler
for (let i = 0; i < this._actionListeners.length; ++i) {
let listener = this._actionListeners[i];
for (let i = 0; i < listeners.length; ++i) {
let listener = listeners[i];
let actionHandler = listener["on" + aName];
if (actionHandler) {
actionHandler.apply(listener, aArgs);

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

@ -270,9 +270,11 @@ StyleEditorChrome.prototype = {
aArgs.unshift(this);
}
// trigger all listeners that have this named handler
for (let i = 0; i < this._listeners.length; ++i) {
let listener = this._listeners[i];
// copy the list of listeners to allow adding/removing listeners in handlers
let listeners = this._listeners.concat();
// trigger all listeners that have this named handler.
for (let i = 0; i < listeners.length; i++) {
let listener = listeners[i];
let handler = listener["on" + aName];
if (handler) {
handler.apply(listener, aArgs);
@ -329,10 +331,10 @@ StyleEditorChrome.prototype = {
{
this._resetChrome();
this._document.title = _("chromeWindowTitle",
this.contentDocument.title || this.contentDocument.location.href);
let document = this.contentDocument;
this._document.title = _("chromeWindowTitle",
document.title || document.location.href);
for (let i = 0; i < document.styleSheets.length; ++i) {
let styleSheet = document.styleSheets[i];
@ -352,6 +354,79 @@ StyleEditorChrome.prototype = {
}, this);
},
/**
* selects a stylesheet and optionally moves the cursor to a selected line
*
* @param {CSSStyleSheet} [aSheet]
* Stylesheet that should be selected. If a stylesheet is not passed
* and the editor is not initialized we focus the first stylesheet. If
* a stylesheet is not passed and the editor is initialized we ignore
* the call.
* @param {Number} [aLine]
* Line to which the caret should be moved (one-indexed).
* @param {Number} [aCol]
* Column to which the caret should be moved (one-indexed).
*/
selectStyleSheet: function SEC_selectSheet(aSheet, aLine, aCol)
{
let select = function DEC_select(aEditor) {
let summary = aSheet ? this.getSummaryElementForEditor(aEditor)
: this._view.getSummaryElementByOrdinal(0);
let setCaret = false;
if (aLine || aCol) {
aLine = aLine || 1;
aCol = aCol || 1;
setCaret = true;
}
if (!aEditor.sourceEditor) {
// If a line or column was specified we move the caret appropriately.
if (setCaret) {
aEditor.addActionListener({
onAttach: function SEC_selectSheet_onAttach()
{
aEditor.removeActionListener(this);
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
}
});
}
this._view.activeSummary = summary;
} else {
this._view.activeSummary = summary;
// If a line or column was specified we move the caret appropriately.
if (setCaret) {
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
}
}
}.bind(this);
if (!this.editors.length) {
// We are in the main initialization phase so we wait for the editor
// containing the target stylesheet to be added and select the target
// stylesheet, optionally moving the cursor to a selected line.
this.addChromeListener({
onEditorAdded: function SEC_selectSheet_onEditorAdded(aChrome, aEditor) {
if ((!aSheet && aEditor.styleSheetIndex == 0) ||
aEditor.styleSheet == aSheet) {
aChrome.removeChromeListener(this);
select(aEditor);
}
}
});
} else if (aSheet) {
// We are already initialized and a stylesheet has been specified. Here
// we iterate through the editors and select the one containing the target
// stylesheet, optionally moving the cursor to a selected line.
for each (let editor in this.editors) {
if (editor.styleSheet == aSheet) {
select(editor);
break;
}
}
}
},
/**
* Disable all UI, effectively making editors read-only.
* This is automatically called when no content window is attached.
@ -455,9 +530,8 @@ StyleEditorChrome.prototype = {
}
}, false);
// autofocus the first or new stylesheet
if (editor.styleSheetIndex == 0 ||
editor.hasFlag(StyleEditorFlags.NEW)) {
// autofocus new stylesheets
if (editor.hasFlag(StyleEditorFlags.NEW)) {
this._view.activeSummary = aSummary;
}

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

@ -132,8 +132,10 @@
<xul:script type="application/javascript"><![CDATA[
Components.utils.import("resource:///modules/devtools/StyleEditorChrome.jsm");
let chromeRoot = document.getElementById("style-editor-chrome");
let contentWindow = window.arguments[0];
let args = window.arguments[0].wrappedJSObject;
let contentWindow = args.contentWindow;
let chrome = new StyleEditorChrome(chromeRoot, contentWindow);
chrome.selectStyleSheet(args.selectedStyleSheet, args.line, args.col);
window.styleEditorChrome = chrome;
]]></xul:script>
</xul:window>

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

@ -51,6 +51,7 @@ _BROWSER_TEST_FILES = \
browser_styleeditor_init.js \
browser_styleeditor_loading.js \
browser_styleeditor_new.js \
browser_styleeditor_passedinsheet.js \
browser_styleeditor_pretty.js \
browser_styleeditor_readonly.js \
browser_styleeditor_reopen.js \

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

@ -0,0 +1,61 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TESTCASE_URI = TEST_BASE + "simple.html";
const LINE = 6;
const COL = 2;
let editor = null;
let sheet = null;
function test()
{
waitForExplicitFinish();
gBrowser.selectedBrowser.addEventListener("load", function () {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
run();
}, true);
content.location = TESTCASE_URI;
}
function run()
{
sheet = content.document.styleSheets[1];
launchStyleEditorChrome(function attachListeners(aChrome) {
aChrome.addChromeListener({
onEditorAdded: checkSourceEditor
});
}, sheet, LINE, COL);
}
function checkSourceEditor(aChrome, aEditor)
{
if (!aEditor.sourceEditor) {
aEditor.addActionListener({
onAttach: function (aEditor) {
aEditor.removeActionListener(this);
validate(aEditor);
}
});
} else {
validate(aEditor);
}
}
function validate(aEditor)
{
info("validating style editor");
let sourceEditor = aEditor.sourceEditor;
let caretPosition = sourceEditor.getCaretPosition();
is(caretPosition.line, LINE - 1, "caret row is correct"); // index based
is(caretPosition.col, COL - 1, "caret column is correct");
is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
finishUp();
}
function finishUp()
{
editor = sheet = null;
finish();
}

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

@ -19,9 +19,9 @@ function cleanup()
}
}
function launchStyleEditorChrome(aCallback)
function launchStyleEditorChrome(aCallback, aSheet, aLine, aCol)
{
gChromeWindow = StyleEditor.openChrome();
gChromeWindow = StyleEditor.openChrome(aSheet, aLine, aCol);
if (gChromeWindow.document.readyState != "complete") {
gChromeWindow.addEventListener("load", function onChromeLoad() {
gChromeWindow.removeEventListener("load", onChromeLoad, true);
@ -34,12 +34,12 @@ function launchStyleEditorChrome(aCallback)
}
}
function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback)
function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback, aSheet, aLine, aCol)
{
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
launchStyleEditorChrome(aCallback);
launchStyleEditorChrome(aCallback, aSheet, aLine, aCol);
}, true);
}

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

@ -273,6 +273,7 @@ CssHtmlTree.prototype = {
this._matchedProperties = null;
if (this.htmlComplete) {
this.refreshSourceFilter();
this.refreshPanel();
} else {
if (this._refreshProcess) {
@ -281,6 +282,9 @@ CssHtmlTree.prototype = {
CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
// Refresh source filter ... this must be done after templateRoot has been
// processed.
this.refreshSourceFilter();
this.numVisibleProperties = 0;
let fragment = this.doc.createDocumentFragment();
this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, {
@ -362,21 +366,28 @@ CssHtmlTree.prototype = {
},
/**
* The change event handler for the onlyUserStyles checkbox. When
* onlyUserStyles.checked is true we do not display properties that have no
* matched selectors, and we do not display UA styles. If .checked is false we
* do display even properties with no matched selectors, and we include the UA
* styles.
* The change event handler for the onlyUserStyles checkbox.
*
* @param {Event} aEvent the DOM Event object.
*/
onlyUserStylesChanged: function CssHtmltree_onlyUserStylesChanged(aEvent)
{
this.refreshSourceFilter();
this.refreshPanel();
},
/**
* When onlyUserStyles.checked is true we only display properties that have
* matched selectors and have been included by the document or one of the
* document's stylesheets. If .checked is false we display all properties
* including those that come from UA stylesheets.
*/
refreshSourceFilter: function CssHtmlTree_setSourceFilter()
{
this._matchedProperties = null;
this.cssLogic.sourceFilter = this.showOnlyUserStyles ?
CssLogic.FILTER.ALL :
CssLogic.FILTER.UA;
this.refreshPanel();
},
/**
@ -974,4 +985,24 @@ SelectorView.prototype = {
return result;
},
/**
* When a css link is clicked this method is called in order to either:
* 1. Open the link in view source (for element style attributes).
* 2. Open the link in the style editor.
*
* @param aEvent The click event
*/
openStyleEditor: function(aEvent)
{
if (this.selectorInfo.selector._cssRule._cssSheet) {
let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
let line = this.selectorInfo.ruleLine;
this.tree.win.StyleEditor.openChrome(styleSheet, line);
} else {
let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
this.tree.win.openUILinkIn("view-source:" + href, "window");
}
},
};

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

@ -232,7 +232,7 @@ CssLogic.prototype = {
// Update the CssSheet objects.
this.forEachSheet(function(aSheet) {
aSheet._sheetAllowed = -1;
if (!aSheet.systemSheet && aSheet.sheetAllowed) {
if (aSheet.contentSheet && aSheet.sheetAllowed) {
ruleCount += aSheet.ruleCount;
}
}, this);
@ -345,7 +345,7 @@ CssLogic.prototype = {
let sheets = [];
this.forEachSheet(function (aSheet) {
if (!aSheet.systemSheet) {
if (aSheet.contentSheet) {
sheets.push(aSheet);
}
}, this);
@ -395,7 +395,7 @@ CssLogic.prototype = {
}
sheet = new CssSheet(this, aDomSheet, aIndex);
if (sheet.sheetAllowed && !sheet.systemSheet) {
if (sheet.sheetAllowed && sheet.contentSheet) {
this._ruleCount += sheet.ruleCount;
}
@ -569,7 +569,7 @@ CssLogic.prototype = {
this.forEachSheet(function (aSheet) {
// We do not show unmatched selectors from system stylesheets
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
return;
}
@ -664,7 +664,7 @@ CssLogic.prototype = {
sheet._passId = this._passId;
}
if (filter !== CssLogic.FILTER.UA && sheet.systemSheet) {
if (filter === CssLogic.FILTER.ALL && !sheet.contentSheet) {
continue;
}
@ -710,7 +710,7 @@ CssLogic.prototype = {
let result = {};
this.forSomeSheets(function (aSheet) {
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
return false;
}
@ -865,29 +865,23 @@ XPCOMUtils.defineLazyGetter(CssLogic, "_strings", function() Services.strings
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
/**
* Is the given property sheet a system (user agent) stylesheet?
* Is the given property sheet a content stylesheet?
*
* @param {CSSStyleSheet} aSheet a stylesheet
* @return {boolean} true if the given stylesheet is a system stylesheet or
* @return {boolean} true if the given stylesheet is a content stylesheet,
* false otherwise.
*/
CssLogic.isSystemStyleSheet = function CssLogic_isSystemStyleSheet(aSheet)
CssLogic.isContentStylesheet = function CssLogic_isContentStylesheet(aSheet)
{
if (!aSheet) {
// All sheets with owner nodes have been included by content.
if (aSheet.ownerNode) {
return true;
}
let url = aSheet.href;
if (!url) return false;
if (url.length === 0) return true;
// Check for http[s]
if (url[0] === 'h') return false;
if (url.substr(0, 9) === "resource:") return true;
if (url.substr(0, 7) === "chrome:") return true;
if (url === "XPCSafeJSObjectWrapper.cpp") return true;
if (url.substr(0, 6) === "about:") return true;
// If the sheet has a CSSImportRule we need to check the parent stylesheet.
if (aSheet.ownerRule instanceof Ci.nsIDOMCSSImportRule) {
return CssLogic.isContentStylesheet(aSheet.parentStyleSheet);
}
return false;
};
@ -942,7 +936,7 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
{
this._cssLogic = aCssLogic;
this.domSheet = aDomSheet;
this.index = this.systemSheet ? -100 * aIndex : aIndex;
this.index = this.contentSheet ? aIndex : -100 * aIndex;
// Cache of the sheets href. Cached by the getter.
this._href = null;
@ -960,21 +954,21 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
CssSheet.prototype = {
_passId: null,
_systemSheet: null,
_contentSheet: null,
_mediaMatches: null,
/**
* Tells if the stylesheet is provided by the browser or not.
*
* @return {boolean} true if this is a browser-provided stylesheet, or false
* @return {boolean} false if this is a browser-provided stylesheet, or true
* otherwise.
*/
get systemSheet()
get contentSheet()
{
if (this._systemSheet === null) {
this._systemSheet = CssLogic.isSystemStyleSheet(this.domSheet);
if (this._contentSheet === null) {
this._contentSheet = CssLogic.isContentStylesheet(this.domSheet);
}
return this._systemSheet;
return this._contentSheet;
},
/**
@ -1048,7 +1042,7 @@ CssSheet.prototype = {
this._sheetAllowed = true;
let filter = this._cssLogic.sourceFilter;
if (filter === CssLogic.FILTER.ALL && this.systemSheet) {
if (filter === CssLogic.FILTER.ALL && !this.contentSheet) {
this._sheetAllowed = false;
}
if (filter !== CssLogic.FILTER.ALL && filter !== CssLogic.FILTER.UA) {
@ -1202,13 +1196,13 @@ function CssRule(aCssSheet, aDomRule, aElement)
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
this.source = this._cssSheet.shortSource + ":" + this.line;
this.href = this._cssSheet.href;
this.systemRule = this._cssSheet.systemSheet;
this.contentRule = this._cssSheet.contentSheet;
} else if (aElement) {
this._selectors = [ new CssSelector(this, "@element.style") ];
this.line = -1;
this.source = CssLogic.l10n("rule.sourceElement");
this.href = "#";
this.systemRule = false;
this.contentRule = true;
this.sourceElement = aElement;
}
}
@ -1396,12 +1390,12 @@ CssSelector.prototype = {
/**
* Check if the selector comes from a browser-provided stylesheet.
*
* @return {boolean} true if the selector comes from a browser-provided
* @return {boolean} true if the selector comes from a content-provided
* stylesheet, or false otherwise.
*/
get systemRule()
get contentRule()
{
return this._cssRule.systemRule;
return this._cssRule.contentRule;
},
/**
@ -1794,12 +1788,12 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
4 important
5 inline important
*/
let scorePrefix = this.systemRule ? 0 : 2;
let scorePrefix = this.contentRule ? 2 : 0;
if (this.elementStyle) {
scorePrefix++;
}
if (this.important) {
scorePrefix += this.systemRule ? 1 : 2;
scorePrefix += this.contentRule ? 2 : 1;
}
this.specificityScore = "" + scorePrefix + this.specificity.ids +
@ -1902,9 +1896,9 @@ CssSelectorInfo.prototype = {
* @return {boolean} true if the selector comes from a browser-provided
* stylesheet, or false otherwise.
*/
get systemRule()
get contentRule()
{
return this.selector.systemRule;
return this.selector.contentRule;
},
/**
@ -1916,8 +1910,8 @@ CssSelectorInfo.prototype = {
*/
compareTo: function CssSelectorInfo_compareTo(aThat)
{
if (this.systemRule && !aThat.systemRule) return 1;
if (!this.systemRule && aThat.systemRule) return -1;
if (!this.contentRule && aThat.contentRule) return 1;
if (this.contentRule && !aThat.contentRule) return -1;
if (this.elementStyle && !aThat.elementStyle) {
if (!this.important && aThat.important) return 1;

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

@ -38,7 +38,7 @@
*
* ***** END LICENSE BLOCK ***** */
"use strict"
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -181,8 +181,8 @@ ElementStyle.prototype = {
let domRule = domRules.GetElementAt(i);
// XXX: Optionally provide access to system sheets.
let systemSheet = CssLogic.isSystemStyleSheet(domRule.parentStyleSheet);
if (systemSheet) {
let contentSheet = CssLogic.isContentStylesheet(domRule.parentStyleSheet);
if (!contentSheet) {
continue;
}
@ -324,7 +324,7 @@ ElementStyle.prototype = {
aProp.overridden = overridden;
return dirty;
}
}
};
/**
* A single style rule or declaration.
@ -358,11 +358,9 @@ Rule.prototype = {
if (this._title) {
return this._title;
}
let sheet = this.domRule ? this.domRule.parentStyleSheet : null;
this._title = CssLogic.shortSource(sheet);
this._title = CssLogic.shortSource(this.sheet);
if (this.domRule) {
let line = this.elementStyle.domUtils.getRuleLine(this.domRule);
this._title += ":" + line;
this._title += ":" + this.ruleLine;
}
if (this.inherited) {
@ -378,6 +376,26 @@ Rule.prototype = {
return this._title;
},
/**
* The rule's stylesheet.
*/
get sheet()
{
return this.domRule ? this.domRule.parentStyleSheet : null;
},
/**
* The rule's line within a stylesheet
*/
get ruleLine()
{
if (!this.sheet) {
// No stylesheet, no ruleLine
return null;
}
return this.elementStyle.domUtils.getRuleLine(this.domRule);
},
/**
* Create a new TextProperty to include in the rule.
*
@ -530,7 +548,7 @@ Rule.prototype = {
this.textProps.push(textProp);
}
},
}
};
/**
* A single property in a rule's cssText.
@ -618,7 +636,7 @@ TextProperty.prototype = {
{
this.rule.removeProperty(this);
}
}
};
/**
@ -643,7 +661,7 @@ TextProperty.prototype = {
* apply to a given element. After construction, the 'element'
* property will be available with the user interface.
*
* @param Document aDocument
* @param Document aDoc
* The document that will contain the rule view.
* @param object aStore
* The CSS rule view can use this object to store metadata
@ -655,7 +673,6 @@ function CssRuleView(aDoc, aStore)
{
this.doc = aDoc;
this.store = aStore;
this.element = this.doc.createElementNS(XUL_NS, "vbox");
this.element.setAttribute("tabindex", "0");
this.element.classList.add("ruleview");
@ -768,6 +785,14 @@ RuleEditor.prototype = {
class: "ruleview-rule-source",
textContent: this.rule.title
});
source.addEventListener("click", function() {
let rule = this.rule;
let evt = this.doc.createEvent("CustomEvent");
evt.initCustomEvent("CssRuleViewCSSLinkClicked", true, false, {
rule: rule,
});
this.element.dispatchEvent(evt);
}.bind(this));
let code = createChild(this.element, "div", {
class: "ruleview-code"
@ -1094,8 +1119,6 @@ TextPropertyEditor.prototype = {
_parseValue: function TextPropertyEditor_parseValue(aValue)
{
let pieces = aValue.split("!", 2);
let value = pieces[0];
let priority = pieces.length > 1 ? pieces[1] : "";
return {
value: pieces[0].trim(),
priority: (pieces.length > 1 ? pieces[1].trim() : "")

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

@ -114,7 +114,7 @@ To visually debug the templates without running firefox, alter the display:none
${selector.humanReadableText(__element)}
</td>
<td class="rule-link">
<a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link"
<a target="_blank" onclick="${selector.openStyleEditor}" class="link"
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
</td>
</tr>

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

@ -59,11 +59,19 @@ _BROWSER_TEST_FILES = \
browser_ruleview_manipulation.js \
browser_ruleview_override.js \
browser_ruleview_ui.js \
browser_bug705707_is_content_stylesheet.js \
head.js \
$(NULL)
_BROWSER_TEST_PAGES = \
browser_bug683672.html \
browser_bug705707_is_content_stylesheet.html \
browser_bug705707_is_content_stylesheet_imported.css \
browser_bug705707_is_content_stylesheet_imported2.css \
browser_bug705707_is_content_stylesheet_linked.css \
browser_bug705707_is_content_stylesheet_script.css \
browser_bug705707_is_content_stylesheet.xul \
browser_bug705707_is_content_stylesheet_xul.css \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

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

@ -0,0 +1,33 @@
<html>
<head>
<title>test</title>
<link href="./browser_bug705707_is_content_stylesheet_linked.css" rel="stylesheet" type="text/css">
<script>
// Load script.css
function loadCSS() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = "./browser_bug705707_is_content_stylesheet_script.css";
document.getElementsByTagName('head')[0].appendChild(link);
}
</script>
<style>
table {
border: 1px solid #000;
}
</style>
</head>
<body onload="loadCSS();">
<table id="target">
<tr>
<td>
<h3>Simple test</h3>
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,100 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the correct stylesheets origins are identified in HTML & XUL
// stylesheets
let doc;
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
"test/browser_bug705707_is_content_stylesheet.html";
const TEST_URI2 = "http://example.com/browser/browser/devtools/styleinspector/" +
"test/browser_bug705707_is_content_stylesheet.xul";
const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(TEST_URI2, null, null);
let tempScope = {};
Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
let CssLogic = tempScope.CssLogic;
function test()
{
waitForExplicitFinish();
addTab(TEST_URI);
browser.addEventListener("load", htmlLoaded, true);
}
function htmlLoaded()
{
browser.removeEventListener("load", htmlLoaded, true);
doc = content.document;
testFromHTML()
}
function testFromHTML()
{
let target = doc.querySelector("#target");
executeSoon(function() {
checkSheets(target);
gBrowser.removeCurrentTab();
openXUL();
});
}
function openXUL()
{
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.ALLOW_ACTION);
addTab(TEST_URI2);
browser.addEventListener("load", xulLoaded, true);
}
function xulLoaded()
{
browser.removeEventListener("load", xulLoaded, true);
doc = content.document;
testFromXUL()
}
function testFromXUL()
{
let target = doc.querySelector("#target");
executeSoon(function() {
checkSheets(target);
finishUp();
});
}
function checkSheets(aTarget)
{
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
let domRules = domUtils.getCSSStyleRules(aTarget);
for (let i = 0, n = domRules.Count(); i < n; i++) {
let domRule = domRules.GetElementAt(i);
let sheet = domRule.parentStyleSheet;
let isContentSheet = CssLogic.isContentStylesheet(sheet);
if (!sheet.href ||
/browser_bug705707_is_content_stylesheet_/.test(sheet.href)) {
ok(isContentSheet, sheet.href + " identified as content stylesheet");
} else {
ok(!isContentSheet, sheet.href + " identified as non-content stylesheet");
}
}
}
function finishUp()
{
info("finishing up");
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.DENY_ACTION);
doc = null;
gBrowser.removeCurrentTab();
finish();
}

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

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
<?xml-stylesheet href="./browser_bug705707_is_content_stylesheet_xul.css"
type="text/css"?>
<!DOCTYPE window>
<window id="testwindow" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<label id="target" value="Simple XUL document" />
</window>

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

@ -0,0 +1,5 @@
@import url("./browser_bug705707_is_content_stylesheet_imported2.css");
#target {
text-decoration: underline;
}

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

@ -0,0 +1,3 @@
#target {
text-decoration: underline;
}

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

@ -0,0 +1,3 @@
table {
border-collapse: collapse;
}

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

@ -0,0 +1,5 @@
@import url("./browser_bug705707_is_content_stylesheet_imported.css");
table {
opacity: 1;
}

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

@ -0,0 +1,3 @@
#target {
font-size: 200px;
}

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

@ -126,6 +126,40 @@ gcli.addCommand({
}
});
/**
* 'edit' command
*/
gcli.addCommand({
name: "edit",
description: gcli.lookup("editDesc"),
manual: gcli.lookup("editManual"),
params: [
{
name: 'resource',
type: {
name: 'resource',
include: 'text/css'
},
description: gcli.lookup("editResourceDesc")
},
{
name: "line",
defaultValue: 1,
type: {
name: "number",
min: 1,
step: 10
},
description: gcli.lookup("editLineToJumpToDesc")
}
],
exec: function(args, context) {
let hud = HUDService.getHudReferenceById(context.environment.hudId);
let StyleEditor = hud.gcliterm.document.defaultView.StyleEditor;
StyleEditor.openChrome(args.resource.element, args.line);
}
});
let breakpoints = [];
/**

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

@ -129,3 +129,23 @@ breakdelRemoved=Breakpoint removed
# 'console close' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
consolecloseDesc=Close the console
# LOCALIZATION NOTE (editDesc) A very short description of the 'edit'
# command. See editManual for a fuller description of what it does. This
# string is designed to be shown in a menu alongside the command name, which
# is why it should be as short as possible.
editDesc=Tweak a page resource
# LOCALIZATION NOTE (editManual) A fuller description of the 'edit' command,
# displayed when the user asks for help on what it does.
editManual=Edit one of the resources that is part of this page (or maybe any generic web resource?)
# LOCALIZATION NOTE (editResourceDesc) A very short string to describe the
# 'resource' parameter to the 'edit' command, which is displayed in a dialog
# when the user is using this command.
editResourceDesc=URL to edit
# LOCALIZATION NOTE (editLineToJumpToDesc) A very short string to describe the
# 'line' parameter to the 'edit' command, which is displayed in a dialog
# when the user is using this command.
editLineToJumpToDesc=Line to jump to

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

@ -68,6 +68,9 @@
.helplink:visited {
text-decoration: none;
}
.link:hover {
text-decoration: underline;
}
.helplink {
display: block;
@ -135,6 +138,7 @@
.rule-link {
text-align: end;
-moz-padding-start: 10px;
cursor: pointer;
}
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -200,7 +204,13 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
}
.ruleview-code {

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

@ -68,6 +68,9 @@
.helplink:visited {
text-decoration: none;
}
.link:hover {
text-decoration: underline;
}
.helplink {
display: block;
@ -137,6 +140,7 @@
.rule-link {
text-align: end;
-moz-padding-start: 10px;
cursor: pointer;
}
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -202,7 +206,13 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
}
.ruleview-code {

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

@ -181,9 +181,9 @@
/* Toolbar shadow behind tabs */
/* This code is only needed for restored windows (i.e. sizemode=normal)
because of the border radius on the toolbar below the tab bar. */
#main-window[sizemode=normal][tabsontop=true] #nav-bar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true][disablechrome] #navigator-toolbox:not(:-moz-lwtheme)::after {
border-top: 1px solid @toolbarShadowColor@;
border-top-left-radius: 3.5px;

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

@ -67,6 +67,9 @@
.helplink:visited {
text-decoration: none;
}
.link:hover {
text-decoration: underline;
}
.helplink {
display: block;
@ -135,6 +138,7 @@
.rule-link {
text-align: end;
-moz-padding-start: 10px;
cursor: pointer;
}
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -200,7 +204,13 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
}
.ruleview-code {

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

@ -84,7 +84,7 @@ DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
MOZ_SOURCE_STAMP ?= $(firstword $(shell hg -R $(topsrcdir)/$(MOZ_BUILD_APP)/.. parent --template="{node|short}\n" 2>/dev/null))
MOZ_SOURCE_STAMP := $(firstword $(shell cd $(topsrcdir)/$(MOZ_BUILD_APP)/.. && hg parent --template="{node|short}\n" 2>/dev/null))
ifdef MOZ_SOURCE_STAMP
DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
endif

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

@ -154,7 +154,7 @@ def build_source_dir(prefix, version):
return source_dir + '/' + prefix + version
binutils_version = "2.21.1"
glibc_version = "2.7" #FIXME: should probably use 2.5.1
glibc_version = "2.5.1"
tar_version = "1.26"
make_version = "3.81"
gcc_version = "4.5.2"
@ -224,7 +224,7 @@ build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
stage1_tool_inst_dir = stage1_dir + '/inst'
stage2_dir = build_dir + '/stage2'
build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc",
build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc -fgnu89-inline",
"CXX" : stage1_tool_inst_dir + "/bin/g++",
"AR" : stage1_tool_inst_dir + "/bin/ar",
"RANLIB" : "true" },

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

@ -40,7 +40,7 @@ diff -ru a/csu/Makefile b/csu/Makefile
diff -ru a/elf/Makefile b/elf/Makefile
--- a/elf/Makefile 2008-10-31 16:35:11.000000000 -0400
+++ b/elf/Makefile 2012-02-16 12:20:00.038593752 -0500
@@ -295,20 +295,13 @@
@@ -295,18 +295,11 @@
z-now-yes = -Wl,-z,now
$(objpfx)ld.so: $(objpfx)librtld.os $(ld-map)
@ -58,12 +58,33 @@ diff -ru a/elf/Makefile b/elf/Makefile
- rm -f $@.lds
+ -Wl,-soname=$(rtld-installed-name) \
+ -Wl,-defsym=_begin=0
readelf -s $@ \
- | awk '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }'
+ | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }'
# interp.c exists just to get this string into the libraries.
CFLAGS-interp.c = -D'RUNTIME_LINKER="$(slibdir)/$(rtld-installed-name)"' \
diff -ru a/localedata/Makefile b/localedata/Makefile
--- a/localedata/Makefile 2006-04-26 01:14:03.000000000 -0400
+++ b/localedata/Makefile 2012-02-17 10:31:24.592345047 -0500
@@ -113,7 +113,7 @@
$(make-target-directory)
rm -f $(@:.gz=) $@
$(INSTALL_DATA) $< $(@:.gz=)
- gzip -9 $(@:.gz=)
+ gzip -9n $(@:.gz=)
# Install the locale source files in the appropriate directory.
$(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install)
diff -ru a/Makeconfig b/Makeconfig
--- a/Makeconfig 2006-07-10 17:42:27.000000000 -0400
+++ b/Makeconfig 2012-02-17 08:28:31.859584817 -0500
@@ -674,7 +674,7 @@
$(foreach lib,$(libof-$(basename $(@F))) \
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \
$(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
-override CFLAGS = -std=gnu99 \
+override CFLAGS = -std=gnu99 -fgnu89-inline \
$(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
$(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
$(CFLAGS-$(@F))
diff -ru a/Makerules b/Makerules
--- a/Makerules 2011-01-17 23:34:07.000000000 -0500
+++ b/Makerules 2012-01-30 08:47:56.565068903 -0500

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

@ -2483,11 +2483,10 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
if (aAllowShortCircuit) {
nsIPrincipal *principal = doGetObjectPrincipal(origObj, false);
// Location is always wrapped (even for same-compartment), so we can
// loosen the check to same-origin instead of same-principal.
NS_ASSERTION(strcmp(jsClass->name, "Location") == 0 ?
NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)) :
result == principal,
// Because of inner window reuse, we can have objects with one principal
// living in a scope with a different (but same-origin) principal. So
// just check same-origin here.
NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
"Principal mismatch. Not good");
}
#endif

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

@ -5,6 +5,7 @@ NSS_DIRS = (('dbm', 'mozilla/dbm'),
('security/nss', 'mozilla/security/nss'),
('security/coreconf', 'mozilla/security/coreconf'),
('security/dbm', 'mozilla/security/dbm'))
NSSCKBI_DIRS = (('security/nss/lib/ckfw/builtins', 'mozilla/security/nss/lib/ckfw/builtins'),)
LIBFFI_DIRS = (('js/ctypes/libffi', 'libffi'),)
CVSROOT_MOZILLA = ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'
@ -91,6 +92,13 @@ elif action in ('update_nss'):
options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
do_cvs_export(NSS_DIRS, tag, options.cvsroot, options.cvs)
print >>file("security/nss/TAG-INFO", "w"), tag
print >>file("security/nss/TAG-INFO-CKBI", "w"), tag
elif action in ('update_nssckbi'):
tag, = args[1:]
if not options.cvsroot:
options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
do_cvs_export(NSSCKBI_DIRS, tag, options.cvsroot, options.cvs)
print >>file("security/nss/TAG-INFO-CKBI", "w"), tag
elif action in ('update_libffi'):
tag, = args[1:]
if not options.cvsroot:

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

@ -51,6 +51,7 @@ use vars qw(
$MICRO_VERSION
$opt_debug
$opt_template
$opt_uaversion
$opt_help
);
@ -60,7 +61,7 @@ push(@INC,$SCRIPTDIR);
require "Moz/Milestone.pm";
&GetOptions('topsrcdir=s' => \$TOPSRCDIR, 'srcdir=s' => \$SRCDIR, 'objdir=s' => \$OBJDIR, 'debug', 'help', 'template');
&GetOptions('topsrcdir=s' => \$TOPSRCDIR, 'srcdir=s' => \$SRCDIR, 'objdir=s' => \$OBJDIR, 'debug', 'help', 'template', 'uaversion');
if (defined($opt_help)) {
&usage();
@ -100,13 +101,19 @@ if (defined(@TEMPLATE_FILE)) {
warn("$0: No such file $TFILE!\n");
}
}
} elsif(defined($opt_uaversion)) {
my $uaversion = Moz::Milestone::getMilestoneMajor($milestone) . "." .
Moz::Milestone::getMilestoneMinor($milestone);
# strip off trailing pre-release indicators
$uaversion =~ s/[a-z]+\d*$//;
print "$uaversion\n";
} else {
print "$milestone\n";
}
sub usage() {
print <<END
`milestone.pl [--topsrcdir TOPSRCDIR] [--objdir OBJDIR] [--srcdir SRCDIR] --template [file list]` # will build file list from .tmpl files
`milestone.pl [--topsrcdir TOPSRCDIR] [--objdir OBJDIR] [--srcdir SRCDIR] --template [file list] --uaversion` # will build file list from .tmpl files
END
;
}

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

@ -225,14 +225,7 @@ if test -n "$L10NBASEDIR"; then
if test "$L10NBASEDIR" = "yes" -o "$L10NBASEDIR" = "no"; then
AC_MSG_ERROR([--with-l10n-base must specify a path])
elif test -d "$L10NBASEDIR"; then
case "$host_os" in
mingw*)
L10NBASEDIR=`cd "$L10NBASEDIR" && pwd -W`
;;
*)
L10NBASEDIR=`cd "$L10NBASEDIR" && pwd`
;;
esac
L10NBASEDIR=`cd "$L10NBASEDIR" && pwd`
else
AC_MSG_ERROR([Invalid value --with-l10n-base, $L10NBASEDIR doesn't exist])
fi
@ -2266,6 +2259,7 @@ fi
dnl Get mozilla version from central milestone file
MOZILLA_VERSION=`$PERL $srcdir/config/milestone.pl -topsrcdir $srcdir`
MOZILLA_UAVERSION=`$PERL $srcdir/config/milestone.pl -topsrcdir $srcdir -uaversion`
dnl Get version of various core apps from the version files.
FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
@ -2276,6 +2270,7 @@ fi
AC_DEFINE_UNQUOTED(MOZILLA_VERSION,"$MOZILLA_VERSION")
AC_DEFINE_UNQUOTED(MOZILLA_VERSION_U,$MOZILLA_VERSION)
AC_DEFINE_UNQUOTED(MOZILLA_UAVERSION,"$MOZILLA_UAVERSION")
MOZ_DOING_LTO(lto_is_enabled)
@ -4092,6 +4087,56 @@ if test "$ac_cv_thread_keyword" = yes -a "$MOZ_LINKER" != 1; then
esac
fi
dnl Using the custom linker on ARMv6 requires 16k alignment of ELF segments.
if test -n "$MOZ_LINKER"; then
if test "$CPU_ARCH" = arm; then
dnl Determine the target ARM architecture (5 for ARMv5, v5T, v5E, etc.; 6 for ARMv6, v6K, etc.)
ARM_ARCH=`${CC-cc} ${CFLAGS} -dM -E - < /dev/null | sed -n 's/.*__ARM_ARCH_\([[0-9]]*\).*/\1/p'`
dnl When building for < ARMv7, we need to ensure 16k alignment of ELF segments
if test -n "$ARM_ARCH" && test "$ARM_ARCH" -lt 7; then
LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=0x4000"
_SUBDIR_LDFLAGS="$_SUBDIR_LDFLAGS -Wl,-z,max-page-size=0x4000"
fi
fi
fi
dnl The custom linker doesn't support text relocations, but NDK >= r6b
dnl creates some (http://code.google.com/p/android/issues/detail?id=23203)
dnl We however want to avoid these text relocations, and this can be done
dnl by making gcc not link crtbegin and crtend. In the broken NDKs, crtend
dnl doesn't contain anything at all, beside placeholders for some sections,
dnl and crtbegin only contains a finalizer function that calls
dnl __cxa_finalize. The custom linker actually takes care of calling
dnl __cxa_finalize when the library doesn't call it itself, which makes it
dnl safe not to link crtbegin. Besides, previous versions of the NDK didn't
dnl link crtbegin and crtend at all.
if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$OS_TARGET" = "Android"; then
AC_CACHE_CHECK([whether the CRT objects have text relocations],
ac_cv_crt_has_text_relocations,
[echo 'int foo() { return 0; }' > conftest.cpp
if AC_TRY_COMMAND(${CXX-g++} -o conftest${DLL_SUFFIX} $CXXFLAGS $DSO_LDOPTS $LDFLAGS conftest.cpp $LIBS 1>&5) &&
test -s conftest${DLL_SUFFIX}; then
if readelf -d conftest${DLL_SUFFIX} | grep TEXTREL > /dev/null; then
ac_cv_crt_has_text_relocations=yes
else
ac_cv_crt_has_text_relocations=no
fi
else
AC_ERROR([couldn't compile a simple C file])
fi
rm -rf conftest*])
if test "$ac_cv_crt_has_text_relocations" = yes; then
dnl While we want libraries to skip the CRT files, we don't want
dnl executables to be treated the same way. We thus set the flag
dnl in DSO_LDOPTS and not LDFLAGS. However, to pass it to nspr,
dnl we need to use LDFLAGS because nspr doesn't inherit DSO_LDOPTS.
dnl Using LDFLAGS in nspr is safe, since we only really build
dnl libraries there.
DSO_LDOPTS="$DSO_LDOPTS -nostartfiles"
NSPR_LDFLAGS=-nostartfiles
fi
fi
dnl Check for the existence of various allocation headers/functions
MALLOC_H=
@ -4929,7 +4974,6 @@ cairo-gonk)
MOZ_PDF_PRINTING=1
MOZ_B2G_RIL=1
MOZ_TOUCH=1
MOZ_B2G_BT=1
;;
esac
@ -5482,6 +5526,15 @@ if test -n "$MOZ_ANDROID_HISTORY"; then
AC_DEFINE(MOZ_ANDROID_HISTORY)
fi
dnl ========================================================
dnl = Build with the Android Java compositor
dnl ========================================================
if test -n "$MOZ_JAVA_COMPOSITOR"; then
dnl Do this if defined in confvars.sh
AC_DEFINE(MOZ_JAVA_COMPOSITOR)
fi
dnl ========================================================
dnl = Disable WebSMS backend
dnl ========================================================
@ -9106,7 +9159,11 @@ if test -z "$MOZ_NATIVE_NSPR"; then
_SAVE_CPPFLAGS="$CPPFLAGS"
export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
fi
_SAVE_LDFLAGS="$LDFLAGS"
export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
AC_OUTPUT_SUBDIRS(nsprpub)
unset LDFLAGS
LDFLAGS="$_SAVE_LDFLAGS"
if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no; then
unset CPPFLAGS
CPPFLAGS="$_SAVE_CFLAGS"

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

@ -920,7 +920,7 @@ public:
/**
* Determing language. Look at the nearest ancestor element that has a lang
* attribute in the XML namespace or is an HTML element and has a lang in
* attribute in the XML namespace or is an HTML/SVG element and has a lang in
* no namespace attribute.
*/
void GetLang(nsAString& aResult) const {
@ -930,7 +930,7 @@ public:
// XHTML1 section C.7).
bool hasAttr = content->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang,
aResult);
if (!hasAttr && content->IsHTML()) {
if (!hasAttr && (content->IsHTML() || content->IsSVG())) {
hasAttr = content->GetAttr(kNameSpaceID_None, nsGkAtoms::lang,
aResult);
}

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

@ -67,7 +67,7 @@ typedef unsigned long long nsContentViewId;
* These APIs are designed to be used with nsIDOMWindowUtils
* setDisplayPort() and setResolution().
*/
[scriptable, uuid(fbd25468-d2cf-487b-bc58-a0e105398b47)]
[scriptable, uuid(c04c5c40-fa2a-4e9c-94f5-b362a10a86cb)]
interface nsIContentView : nsISupports
{
/**
@ -265,6 +265,13 @@ interface nsIFrameLoader : nsISupports
* Defaults to true.
*/
attribute boolean clipSubdocument;
/**
* If false, then the subdocument's scroll coordinates will not be clamped
* to their scroll boundaries.
* Defaults to true.
*/
attribute boolean clampScrollPosition;
};
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);

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

@ -311,24 +311,18 @@ public:
friend class nsAttrAndChildArray;
#ifdef MOZILLA_INTERNAL_API
static nsINode *sOrphanNodeHead;
nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
: mNodeInfo(aNodeInfo),
mParent(nsnull),
mFlags(0),
mBoolFlags(1 << NodeIsOrphan),
mNextOrphanNode(sOrphanNodeHead->mNextOrphanNode),
mPreviousOrphanNode(sOrphanNodeHead),
mBoolFlags(0),
mNextSibling(nsnull),
mPreviousSibling(nsnull),
mFirstChild(nsnull),
mSlots(nsnull)
{
NS_ASSERTION(GetBoolFlag(NodeIsOrphan),
"mBoolFlags not initialized correctly!");
mNextOrphanNode->mPreviousOrphanNode = this;
sOrphanNodeHead->mNextOrphanNode = this;
}
#endif
virtual ~nsINode();
@ -1109,63 +1103,8 @@ public:
nsresult IsEqualNode(nsIDOMNode* aOther, bool* aReturn);
bool IsEqualTo(nsINode* aOther);
nsIContent* GetNextSibling() const
{
return NS_UNLIKELY(IsOrphan()) ? nsnull : mNextSibling;
}
nsIContent* GetPreviousSibling() const
{
return NS_UNLIKELY(IsOrphan()) ? nsnull : mPreviousSibling;
}
// Returns true if this node is an orphan node
bool IsOrphan() const
{
#ifdef MOZILLA_INTERNAL_API
NS_ASSERTION(this != sOrphanNodeHead, "Orphan node head orphan check?!");
#endif
return GetBoolFlag(NodeIsOrphan);
}
#ifdef MOZILLA_INTERNAL_API
// Mark this node as an orphan node. This marking is only relevant
// for this node itself, not its children. Its children are not
// considered orphan until they themselves are removed from their
// parent and get marked as orphans.
void MarkAsOrphan()
{
NS_ASSERTION(!IsOrphan(), "Orphan node orphaned again?");
NS_ASSERTION(this != sOrphanNodeHead, "Orphan node head orphaned?!");
mNextOrphanNode = sOrphanNodeHead->mNextOrphanNode;
mPreviousOrphanNode = sOrphanNodeHead;
mNextOrphanNode->mPreviousOrphanNode = this;
sOrphanNodeHead->mNextOrphanNode = this;
SetBoolFlag(NodeIsOrphan);
}
// Unmark this node as an orphan node. Do this before inserting this
// node into a parent or otherwise associating it with some other
// owner.
void MarkAsNonOrphan()
{
NS_ASSERTION(IsOrphan(), "Non-orphan node un-orphaned");
NS_ASSERTION(this != sOrphanNodeHead, "Orphan node head unorphaned?!");
NS_ASSERTION(!mParent, "Must not have a parent here!");
mPreviousOrphanNode->mNextOrphanNode = mNextOrphanNode;
mNextOrphanNode->mPreviousOrphanNode = mPreviousOrphanNode;
mPreviousOrphanNode = nsnull;
mNextOrphanNode = nsnull;
ClearBoolFlag(NodeIsOrphan);
}
#endif
static void Init();
nsIContent* GetNextSibling() const { return mNextSibling; }
nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
/**
* Get the next node in the pre-order tree traversal of the DOM. If
@ -1312,8 +1251,6 @@ private:
NodeHasExplicitBaseURI,
// Set if the element has some style states locked
ElementHasLockedStyleStates,
// Set if the node is an orphan node.
NodeIsOrphan,
// Guard value
BooleanFlagCount
};
@ -1529,24 +1466,8 @@ private:
PRUint32 mBoolFlags;
protected:
union {
// mNextSibling is used when this node is part of a DOM tree
nsIContent* mNextSibling;
// mNextOrphanNode is used when this is in the linked list of
// orphan nodes.
nsINode *mNextOrphanNode;
};
union {
// mPreviousSibling is used when this node is part of a DOM tree
nsIContent* mPreviousSibling;
// mPreviousOrphanNode is used when this is in the linked list of
// orphan nodes.
nsINode* mPreviousOrphanNode;
};
nsIContent* mNextSibling;
nsIContent* mPreviousSibling;
nsIContent* mFirstChild;
// Storage for more members that are usually not needed; allocated lazily.

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

@ -183,9 +183,9 @@ interface nsIXMLHttpRequest : nsISupports
* part of a multipart request, not from the original channel.
*
* @returns A string containing all of the response headers.
* NULL if the response has not yet been received.
* The empty string if the response has not yet been received.
*/
string getAllResponseHeaders();
DOMString getAllResponseHeaders();
/**
* Returns the text of the header with the specified name for

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

@ -554,10 +554,9 @@ mozSanitizingHTMLSerializer::IsAllowedAttribute(nsHTMLTag aTag,
NS_ENSURE_TRUE(attr_bag, false);
bool allowed;
nsAutoString attr(anAttributeName);
ToLowerCase(attr);
rv = attr_bag->Has(NS_LossyConvertUTF16toASCII(attr).get(),
&allowed);
nsCAutoString attr;
ToLowerCase(NS_ConvertUTF16toUTF8(anAttributeName), attr);
rv = attr_bag->Has(attr.get(), &allowed);
if (NS_FAILED(rv))
return false;

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

@ -232,19 +232,13 @@ nsAttrAndChildArray::TakeChildAt(PRUint32 aPos)
PRUint32 childCount = ChildCount();
void** pos = mImpl->mBuffer + AttrSlotsSize() + aPos;
nsIContent* child = static_cast<nsIContent*>(*pos);
MOZ_ASSERT(!child->IsOrphan(), "Child should not be an orphan here");
if (child->mPreviousSibling) {
child->mPreviousSibling->mNextSibling = child->mNextSibling;
}
if (child->mNextSibling) {
child->mNextSibling->mPreviousSibling = child->mPreviousSibling;
}
// Mark the child as an orphan now that it's no longer associated
// with its old parent.
child->MarkAsOrphan();
child->mPreviousSibling = child->mNextSibling = nsnull;
memmove(pos, pos + 1, (childCount - aPos - 1) * sizeof(nsIContent*));
SetChildCount(childCount - 1);
@ -663,12 +657,8 @@ nsAttrAndChildArray::Clear()
// making this false so tree teardown doesn't end up being
// O(N*D) (number of nodes times average depth of tree).
child->UnbindFromTree(false); // XXX is it better to let the owner do this?
// Mark the child as an orphan now that it's no longer a child of
// its old parent, and make sure to unlink our kids from each
// other, since someone else could stil be holding references to
// some of them.
child->MarkAsOrphan();
// Make sure to unlink our kids from each other, since someone
// else could stil be holding references to some of them.
// XXXbz We probably can't push this assignment down into the |aNullParent|
// case of UnbindFromTree because we still need the assignment in
@ -678,6 +668,7 @@ nsAttrAndChildArray::Clear()
// to point to each other but keep the kid being removed pointing to them
// through ContentRemoved so consumers can find where it used to be in the
// list?
child->mPreviousSibling = child->mNextSibling = nsnull;
NS_RELEASE(child);
}
@ -831,16 +822,8 @@ inline void
nsAttrAndChildArray::SetChildAtPos(void** aPos, nsIContent* aChild,
PRUint32 aIndex, PRUint32 aChildCount)
{
MOZ_ASSERT(aChild->IsOrphan(), "aChild should be an orphan here");
NS_PRECONDITION(aChild->IsOrphan() || !aChild->GetNextSibling(),
"aChild should be orphan and have no next sibling!");
NS_PRECONDITION(aChild->IsOrphan() || !aChild->GetPreviousSibling(),
"aChild should be orphan and have no prev sibling!");
// Unmark this child as an orphan now that it's a child of its new
// parent.
aChild->MarkAsNonOrphan();
NS_PRECONDITION(!aChild->GetNextSibling(), "aChild with next sibling?");
NS_PRECONDITION(!aChild->GetPreviousSibling(), "aChild with prev sibling?");
*aPos = aChild;
NS_ADDREF(aChild);

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

@ -48,6 +48,7 @@
#include "nsCopySupport.h"
#include "nsIDOMUIEvent.h"
#include "nsISelection.h"
#include "nsISelectionController.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMEvent.h"
@ -70,6 +71,7 @@
#include "nsIDocShell.h"
#include "nsIContent.h"
#include "nsIImageLoadingContent.h"
#include "nsITextControlElement.h"
#include "nsUnicharUtils.h"
#include "nsIURL.h"
#include "nsIDocument.h"
@ -84,37 +86,6 @@
#include "imgIRequest.h"
#include "nsDOMDataTransfer.h"
// private clipboard data flavors for html copy, used by editor when pasting
#define kHTMLContext "text/_moz_htmlcontext"
#define kHTMLInfo "text/_moz_htmlinfo"
// if aNode is null, use the selection from the window
static nsresult
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
nsIContent* aNode,
nsITransferable** aTransferable)
{
NS_ENSURE_ARG_POINTER(aWindow);
nsCOMPtr<nsIDOMDocument> domDoc;
aWindow->GetDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
nsresult rv;
if (aNode) {
rv = nsCopySupport::GetTransferableForNode(aNode, doc, aTransferable);
} else {
nsCOMPtr<nsISelection> selection;
aWindow->GetSelection(getter_AddRefs(selection));
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
aTransferable);
}
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
class NS_STACK_CLASS DragDataProducer
{
public:
@ -124,7 +95,7 @@ public:
bool aIsAltKeyPressed);
nsresult Produce(nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag,
bool* aDragSelection,
nsISelection** aSelection,
nsIContent** aDragNode);
private:
@ -172,7 +143,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag,
bool* aDragSelection,
nsISelection** aSelection,
nsIContent** aDragNode)
{
NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG);
@ -181,7 +152,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
DragDataProducer
provider(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed);
return provider.Produce(aDataTransfer, aCanDrag, aDragSelection, aDragNode);
return provider.Produce(aDataTransfer, aCanDrag, aSelection, aDragNode);
}
@ -412,10 +383,10 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
nsresult
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag,
bool* aDragSelection,
nsISelection** aSelection,
nsIContent** aDragNode)
{
NS_PRECONDITION(aCanDrag && aDragSelection && aDataTransfer && aDragNode,
NS_PRECONDITION(aCanDrag && aSelection && aDataTransfer && aDragNode,
"null pointer passed to Produce");
NS_ASSERTION(mWindow, "window not set");
NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
@ -424,33 +395,72 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
nsresult rv;
nsIContent* dragNode = nsnull;
*aSelection = nsnull;
// find the selection to see what we could be dragging and if
// what we're dragging is in what is selected.
// Find the selection to see what we could be dragging and if what we're
// dragging is in what is selected. If this is an editable textbox, use
// the textbox's selection, otherwise use the window's selection.
nsCOMPtr<nsISelection> selection;
mWindow->GetSelection(getter_AddRefs(selection));
if (!selection) {
return NS_OK;
}
// check if the node is inside a form control. If so, dragging will be
// handled in editor code (nsPlaintextDataTransfer::DoDrag). Don't set
// aCanDrag to false however, as we still want to allow the drag.
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode;
nsIContent* findFormParent = findFormNode->GetParent();
while (findFormParent) {
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent));
if (form && !form->AllowDraggableChildren()) {
return NS_OK;
nsIContent* editingElement = mSelectionTargetNode->IsEditable() ?
mSelectionTargetNode->GetEditingHost() : nsnull;
nsCOMPtr<nsITextControlElement> textControl(do_QueryInterface(editingElement));
if (textControl) {
nsISelectionController* selcon = textControl->GetSelectionController();
if (selcon) {
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
if (!selection)
return NS_OK;
}
}
else {
mWindow->GetSelection(getter_AddRefs(selection));
if (!selection)
return NS_OK;
// Check if the node is inside a form control. Don't set aCanDrag to false
//however, as we still want to allow the drag.
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode;
nsIContent* findFormParent = findFormNode->GetParent();
while (findFormParent) {
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent));
if (form && !form->AllowDraggableChildren()) {
return NS_OK;
}
findFormParent = findFormParent->GetParent();
}
findFormParent = findFormParent->GetParent();
}
// if set, serialize the content under this node
nsCOMPtr<nsIContent> nodeToSerialize;
*aDragSelection = false;
{
bool isChromeShell = false;
nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mWindow);
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
if (dsti) {
PRInt32 type = -1;
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
type == nsIDocShellTreeItem::typeChrome) {
isChromeShell = true;
}
}
// In chrome shells, only allow dragging inside editable areas.
if (isChromeShell && !editingElement)
return NS_OK;
if (isChromeShell && textControl) {
// Only use the selection if it isn't collapsed.
bool isCollapsed = false;
selection->GetIsCollapsed(&isCollapsed);
if (!isCollapsed)
selection.swap(*aSelection);
}
else {
// In content shells, a number of checks are made below to determine
// whether an image or a link is being dragged. If so, add additional
// data to the data transfer. This is also done for chrome shells, but
// only when in a non-textbox editor.
bool haveSelectedContent = false;
// possible parent link node
@ -490,7 +500,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
return NS_OK;
}
*aDragSelection = true;
selection.swap(*aSelection);
} else if (selectedImageOrLinkNode) {
// an image is selected
image = do_QueryInterface(selectedImageOrLinkNode);
@ -660,20 +670,28 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
}
}
if (nodeToSerialize || *aDragSelection) {
// if we have selected text, use it in preference to the node
if (*aDragSelection) {
nodeToSerialize = nsnull;
}
if (nodeToSerialize || *aSelection) {
mHtmlString.Truncate();
mContextString.Truncate();
mInfoString.Truncate();
mTitleString.Truncate();
nsCOMPtr<nsIDOMDocument> domDoc;
mWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
// if we have selected text, use it in preference to the node
nsCOMPtr<nsITransferable> transferable;
rv = ::GetTransferableForNodeOrSelection(mWindow, nodeToSerialize,
getter_AddRefs(transferable));
NS_ENSURE_SUCCESS(rv, rv);
if (*aSelection) {
rv = nsCopySupport::GetTransferableForSelection(*aSelection, doc,
getter_AddRefs(transferable));
}
else {
rv = nsCopySupport::GetTransferableForNode(nodeToSerialize, doc,
getter_AddRefs(transferable));
}
nsCOMPtr<nsISupportsString> data;
PRUint32 dataSize;
rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
@ -747,15 +765,17 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal);
}
// add a special flavor, even if we don't have html context data
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal);
// add a special flavor for the html context data
if (!mContextString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal);
// add a special flavor if we have html info data
if (!mInfoString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal);
// add the full html
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal);
if (!mHtmlString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal);
// add the plain text. we use the url for text/plain data if an anchor is
// being dragged, rather than the title text of the link or the alt text for

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

@ -78,8 +78,8 @@ public:
* aDataTransfer - the dataTransfer for the drag event.
* aCanDrag - [out] set to true if the drag may proceed, false to stop the
* drag entirely
* aDragSelection - [out] set to true to indicate that a selection is being
* dragged, rather than a specific node
* aSelection - [out] set to the selection being dragged, or null if no
* selection is being dragged.
* aDragNode - [out] the link, image or area being dragged, or null if the
* drag occurred on another element.
*/
@ -89,7 +89,7 @@ public:
bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag,
bool* aDragSelection,
nsISelection** aSelection,
nsIContent** aDragNode);
};

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

@ -362,8 +362,6 @@ nsContentUtils::Init()
return NS_OK;
}
nsINode::Init();
nsresult rv = NS_GetNameSpaceManager(&sNameSpaceManager);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -91,10 +91,6 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
// private clipboard data flavors for html copy, used by editor when pasting
#define kHTMLContext "text/_moz_htmlcontext"
#define kHTMLInfo "text/_moz_htmlinfo"
// copy string data onto the transferable
static nsresult AppendString(nsITransferable *aTransferable,
const nsAString& aString,

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

@ -91,7 +91,6 @@ nsDOMAttribute::~nsDOMAttribute()
{
if (mChild) {
static_cast<nsTextNode*>(mChild)->UnbindFromAttribute();
mChild->MarkAsOrphan();
NS_RELEASE(mChild);
mFirstChild = nsnull;
}
@ -122,7 +121,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
nsINode::Unlink(tmp);
if (tmp->mChild) {
static_cast<nsTextNode*>(tmp->mChild)->UnbindFromAttribute();
tmp->mChild->MarkAsOrphan();
NS_RELEASE(tmp->mChild);
tmp->mFirstChild = nsnull;
}
@ -728,7 +726,6 @@ nsDOMAttribute::EnsureChildState()
if (!value.IsEmpty()) {
NS_NewTextNode(&mChild, mNodeInfo->NodeInfoManager());
mChild->MarkAsNonOrphan();
static_cast<nsTextNode*>(mChild)->BindToAttribute(this);
mFirstChild = mChild;
@ -796,6 +793,5 @@ nsDOMAttribute::doRemoveChild(bool aNotify)
}
child->UnbindFromAttribute();
child->MarkAsOrphan();
}

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

@ -859,7 +859,7 @@ TransferZoomLevels(nsIDocument* aFromDoc,
return;
toCtxt->SetFullZoom(fromCtxt->GetFullZoom());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize(nsnull));
toCtxt->SetTextZoom(fromCtxt->TextZoom());
}
@ -1579,8 +1579,7 @@ nsDocument::~nsDocument()
nsCycleCollector_DEBUG_wasFreed(static_cast<nsIDocument*>(this));
#endif
NS_ASSERTION(!mIsShowing, "Deleting a currently-showing document");
NS_ASSERTION(IsOrphan(), "Deleted document not an orphan?");
NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
mInDestructor = true;
mInUnlinkOrDeletion = true;
@ -2119,7 +2118,6 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
}
#endif
SetPrincipal(nsnull);
mSecurityInfo = nsnull;
mDocumentLoadGroup = nsnull;
@ -2169,6 +2167,12 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
// Release the stylesheets list.
mDOMStyleSheets = nsnull;
// Release our principal after tearing down the document, rather than before.
// This ensures that, during teardown, the document and the dying window (which
// already nulled out its document pointer and cached the principal) have
// matching principals.
SetPrincipal(nsnull);
// Clear the original URI so SetDocumentURI sets it.
mOriginalURI = nsnull;
@ -5129,11 +5133,9 @@ NS_IMETHODIMP
nsDocument::GetDefaultView(nsIDOMWindow** aDefaultView)
{
*aDefaultView = nsnull;
nsPIDOMWindow* win = GetWindow();
if (!win) {
return NS_OK;
}
return CallQueryInterface(win, aDefaultView);
nsCOMPtr<nsPIDOMWindow> win = GetWindow();
win.forget(aDefaultView);
return NS_OK;
}
NS_IMETHODIMP
@ -8116,7 +8118,7 @@ nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback,
PRInt32 newHandle = ++mFrameRequestCallbackCounter;
bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
FrameRequest *request =
DebugOnly<FrameRequest*> request =
mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
NS_ASSERTION(request, "This is supposed to be infallible!");
if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
@ -8299,11 +8301,8 @@ nsDocument::RemoveImage(imgIRequest* aImage)
NS_ENSURE_ARG_POINTER(aImage);
// Get the old count. It should exist and be > 0.
PRUint32 count;
#ifdef DEBUG
bool found =
#endif
mImageTracker.Get(aImage, &count);
PRUint32 count = 0;
DebugOnly<bool> found = mImageTracker.Get(aImage, &count);
NS_ABORT_IF_FALSE(found, "Removing image that wasn't in the tracker!");
NS_ABORT_IF_FALSE(count > 0, "Entry in the cache tracker with count 0!");
@ -8527,7 +8526,7 @@ public:
NS_IMETHOD Run()
{
if (mDoc->GetWindow()) {
mDoc->GetWindow()->SetFullScreen(mValue);
mDoc->GetWindow()->SetFullScreenInternal(mValue, false);
}
return NS_OK;
}

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

@ -76,6 +76,7 @@
#include "nsFrameLoader.h"
#include "nsIDOMEventTarget.h"
#include "nsIFrame.h"
#include "nsIScrollableFrame.h"
#include "nsSubDocumentFrame.h"
#include "nsDOMError.h"
#include "nsGUIEvent.h"
@ -330,6 +331,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
, mRemoteBrowserShown(false)
, mRemoteFrame(false)
, mClipSubdocument(true)
, mClampScrollPosition(true)
, mCurrentRemoteFrame(nsnull)
, mRemoteBrowser(nsnull)
, mRenderMode(RENDER_MODE_DEFAULT)
@ -1755,6 +1757,38 @@ nsFrameLoader::SetClipSubdocument(bool aClip)
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::GetClampScrollPosition(bool* aResult)
{
*aResult = mClampScrollPosition;
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::SetClampScrollPosition(bool aClamp)
{
mClampScrollPosition = aClamp;
// When turning clamping on, make sure the current position is clamped.
if (aClamp) {
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
if (frame) {
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
if (subdocFrame) {
nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
if (subdocRootFrame) {
nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
GetRootScrollFrameAsScrollable();
if (subdocRootScrollFrame) {
subdocRootScrollFrame->ScrollTo(subdocRootScrollFrame->GetScrollPosition(), nsIScrollableFrame::INSTANT);
}
}
}
}
}
return NS_OK;
}
nsIntSize
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
{

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

@ -289,6 +289,8 @@ public:
bool ShouldClipSubdocument() { return mClipSubdocument; }
bool ShouldClampScrollPosition() { return mClampScrollPosition; }
private:
bool ShouldUseRemoteProcess();
@ -342,6 +344,7 @@ private:
bool mRemoteBrowserShown : 1;
bool mRemoteFrame : 1;
bool mClipSubdocument : 1;
bool mClampScrollPosition : 1;
// XXX leaking
nsCOMPtr<nsIObserver> mChildHost;

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

@ -349,7 +349,8 @@ class MMListenerRemover
{
public:
MMListenerRemover(nsFrameMessageManager* aMM)
: mMM(aMM), mWasHandlingMessage(aMM->mHandlingMessage)
: mWasHandlingMessage(aMM->mHandlingMessage)
, mMM(aMM)
{
mMM->mHandlingMessage = true;
}

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

@ -213,16 +213,9 @@ nsINode::nsSlots::Unlink()
//----------------------------------------------------------------------
nsINode *nsINode::sOrphanNodeHead = nsnull;
nsINode::~nsINode()
{
NS_ASSERTION(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
MOZ_ASSERT(IsOrphan(), "Node should be orphan by the time it's deleted!");
mPreviousOrphanNode->mNextOrphanNode = mNextOrphanNode;
mNextOrphanNode->mPreviousOrphanNode = mPreviousOrphanNode;
}
void*
@ -3269,7 +3262,7 @@ nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
// Unset this since that's what the old code effectively did.
UnsetFlags(NODE_FORCE_XBL_BINDINGS);
#ifdef MOZ_XUL
nsXULElement* xulElem = nsXULElement::FromContent(this);
if (xulElem) {
@ -3863,22 +3856,7 @@ nsGenericElement::SetTextContent(const nsAString& aTextContent)
return nsContentUtils::SetNodeTextContent(this, aTextContent, false);
}
// static
void
nsINode::Init()
{
// Allocate static storage for the head of the list of orphan nodes
static MOZ_ALIGNED_DECL(char orphanNodeListHead[sizeof(nsINode)], 8);
sOrphanNodeHead = reinterpret_cast<nsINode *>(&orphanNodeListHead[0]);
sOrphanNodeHead->mNextOrphanNode = sOrphanNodeHead;
sOrphanNodeHead->mPreviousOrphanNode = sOrphanNodeHead;
sOrphanNodeHead->mFirstChild = reinterpret_cast<nsIContent *>(0xdeadbeef);
sOrphanNodeHead->mParent = reinterpret_cast<nsIContent *>(0xdeadbeef);
}
// static
/* static */
nsresult
nsGenericElement::DispatchEvent(nsPresContext* aPresContext,
nsEvent* aEvent,

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

@ -1100,6 +1100,7 @@ GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
GK_ATOM(headerCSP, "x-content-security-policy")
GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
GK_ATOM(headerXFO, "x-frame-options")
GK_ATOM(x_western, "x-western")
GK_ATOM(xml, "xml")
GK_ATOM(xml_stylesheet, "xml-stylesheet")
GK_ATOM(xmlns, "xmlns")

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

@ -1280,8 +1280,10 @@ nsXMLHttpRequest::CloseRequestWithError(const nsAString& aType,
mState |= aFlag;
// If we're in the destructor, don't risk dispatching an event.
if (mState & XML_HTTP_REQUEST_DELETED)
if (mState & XML_HTTP_REQUEST_DELETED) {
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
return;
}
if (!(mState & (XML_HTTP_REQUEST_UNSENT |
XML_HTTP_REQUEST_OPENED |
@ -1317,31 +1319,47 @@ nsXMLHttpRequest::Abort()
return NS_OK;
}
/* string getAllResponseHeaders (); */
/* DOMString getAllResponseHeaders(); */
NS_IMETHODIMP
nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
nsXMLHttpRequest::GetAllResponseHeaders(nsAString& aResponseHeaders)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
aResponseHeaders.Truncate();
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
*_retval = ToNewCString(EmptyString());
// If the state is UNSENT or OPENED,
// return the empty string and terminate these steps.
if (mState & (XML_HTTP_REQUEST_UNSENT |
XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) {
return NS_OK;
}
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
return NS_OK;
}
if (httpChannel) {
if (nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel()) {
nsRefPtr<nsHeaderVisitor> visitor = new nsHeaderVisitor();
nsresult rv = httpChannel->VisitResponseHeaders(visitor);
if (NS_SUCCEEDED(rv))
*_retval = ToNewCString(visitor->Headers());
}
if (!*_retval) {
*_retval = ToNewCString(EmptyString());
if (NS_SUCCEEDED(httpChannel->VisitResponseHeaders(visitor))) {
aResponseHeaders = NS_ConvertUTF8toUTF16(visitor->Headers());
}
return NS_OK;
}
if (!mChannel) {
return NS_OK;
}
// Even non-http channels supply content type.
nsCAutoString value;
if (NS_SUCCEEDED(mChannel->GetContentType(value))) {
aResponseHeaders.AppendLiteral("Content-Type: ");
aResponseHeaders.Append(NS_ConvertUTF8toUTF16(value));
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) &&
!value.IsEmpty()) {
aResponseHeaders.AppendLiteral(";charset=");
aResponseHeaders.Append(NS_ConvertUTF8toUTF16(value));
}
aResponseHeaders.Append('\n');
}
return NS_OK;
}
@ -1356,6 +1374,37 @@ nsXMLHttpRequest::GetResponseHeader(const nsACString& header,
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
if (!httpChannel) {
// If the state is UNSENT or OPENED,
// return null and terminate these steps.
if (mState & (XML_HTTP_REQUEST_UNSENT |
XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) {
return NS_OK;
}
// Even non-http channels supply content type.
// Remember we don't leak header information from denied cross-site
// requests.
nsresult status;
if (!mChannel ||
NS_FAILED(mChannel->GetStatus(&status)) ||
NS_FAILED(status) ||
!header.LowerCaseEqualsASCII("content-type")) {
return NS_OK;
}
if (NS_FAILED(mChannel->GetContentType(_retval))) {
// Means no content type
_retval.SetIsVoid(true);
return NS_OK;
}
nsCString value;
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) &&
!value.IsEmpty()) {
_retval.Append(";charset=");
_retval.Append(value);
}
return NS_OK;
}

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

@ -22,11 +22,15 @@ function runTests() {
var path = "/tests/content/base/test/";
var passFiles = [['file_XHR_pass1.xml', 'GET', 200],
['file_XHR_pass2.txt', 'GET', 200],
['file_XHR_pass3.txt', 'GET', 200],
['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0],
['data:text/plain,hello%20pass%0A', 'GET', 0],
var passFiles = [['file_XHR_pass1.xml', 'GET', 200, 'text/xml'],
['file_XHR_pass2.txt', 'GET', 200, 'text/plain'],
['file_XHR_pass3.txt', 'GET', 200, 'text/plain'],
['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0, 'text/xml'],
['data:text/plain,hello%20pass%0A', 'GET', 0, 'text/plain'],
['data:,foo', 'GET', 0, 'text/plain;charset=US-ASCII', 'foo'],
['data:text/plain;base64,Zm9v', 'GET', 0, 'text/plain', 'foo'],
['data:text/plain,foo#bar', 'GET', 0, 'text/plain', 'foo'],
['data:text/plain,foo%23bar', 'GET', 0, 'text/plain', 'foo#bar'],
];
var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
@ -36,19 +40,24 @@ var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
for (i = 0; i < passFiles.length; ++i) {
xhr = new XMLHttpRequest();
is(xhr.getResponseHeader("Content-Type"), null, "should be null");
is(xhr.getAllResponseHeaders(), "", "should be empty string");
is(xhr.responseType, "", "wrong initial responseType");
xhr.open(passFiles[i][1], passFiles[i][0], false);
xhr.send(null);
is(xhr.status, passFiles[i][2], "wrong status");
is(xhr.getResponseHeader("Content-Type"), passFiles[i][3], "wrong content type");
var headers = xhr.getAllResponseHeaders();
ok(/(?:^|\n)Content-Type:\s*([^\n]*)\n/i.test(headers) &&
RegExp.$1 === passFiles[i][3], "wrong response headers");
if (xhr.responseXML) {
is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement),
"<res>hello</res>",
"wrong responseXML");
is(xhr.response, "<res>hello</res>\n", "wrong response");
passFiles[i][4] || "<res>hello</res>", "wrong responseXML");
is(xhr.response, passFiles[i][4] || "<res>hello</res>\n", "wrong response");
}
else {
is(xhr.responseText, "hello pass\n", "wrong responseText");
is(xhr.response, "hello pass\n", "wrong response");
is(xhr.responseText, passFiles[i][4] || "hello pass\n", "wrong responseText");
is(xhr.response, passFiles[i][4] || "hello pass\n", "wrong response");
}
}

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

@ -445,7 +445,7 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
JS_GetProperty(cx, argv5, "data", &js_data);
if (js_width == JSVAL_VOID ||
js_height == JSVAL_VOID ||
js_data == JSVAL_VOID)
!js_data.isObject())
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
return JS_FALSE;
@ -566,7 +566,7 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
JS_GetProperty(cx, argv6, "data", &js_data);
if (js_width == JSVAL_VOID ||
js_height == JSVAL_VOID ||
js_data == JSVAL_VOID)
!js_data.isObject())
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
return JS_FALSE;

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

@ -68,6 +68,7 @@ CPPSRCS += \
WebGLContext.cpp \
WebGLContextGL.cpp \
WebGLContextUtils.cpp \
WebGLContextReporter.cpp \
WebGLContextValidate.cpp \
WebGLExtensionStandardDerivatives.cpp \
WebGLExtensionLoseContext.cpp \

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

@ -75,133 +75,6 @@ using namespace mozilla;
using namespace mozilla::gl;
using namespace mozilla::layers;
WebGLMemoryReporter* WebGLMemoryReporter::sUniqueInstance = nsnull;
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureMemoryUsed,
"webgl-texture-memory",
KIND_OTHER,
UNITS_BYTES,
WebGLMemoryReporter::GetTextureMemoryUsed,
"Memory used by WebGL textures. The OpenGL implementation is free to store these textures in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureCount,
"webgl-texture-count",
KIND_OTHER,
UNITS_COUNT,
WebGLMemoryReporter::GetTextureCount,
"Number of WebGL textures.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferMemoryUsed,
"webgl-buffer-memory",
KIND_OTHER,
UNITS_BYTES,
WebGLMemoryReporter::GetBufferMemoryUsed,
"Memory used by WebGL buffers. The OpenGL implementation is free to store these buffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCacheMemoryUsed,
"explicit/webgl/buffer-cache-memory",
KIND_HEAP,
UNITS_BYTES,
WebGLMemoryReporter::GetBufferCacheMemoryUsed,
"Memory used by WebGL buffer caches. The WebGL implementation caches the contents of element array buffers only. This adds up with the webgl-buffer-memory value, but contrary to it, this one represents bytes on the heap, not managed by OpenGL.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCount,
"webgl-buffer-count",
KIND_OTHER,
UNITS_COUNT,
WebGLMemoryReporter::GetBufferCount,
"Number of WebGL buffers.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferMemoryUsed,
"webgl-renderbuffer-memory",
KIND_OTHER,
UNITS_BYTES,
WebGLMemoryReporter::GetRenderbufferMemoryUsed,
"Memory used by WebGL renderbuffers. The OpenGL implementation is free to store these renderbuffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferCount,
"webgl-renderbuffer-count",
KIND_OTHER,
UNITS_COUNT,
WebGLMemoryReporter::GetRenderbufferCount,
"Number of WebGL renderbuffers.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderSourcesSize,
"explicit/webgl/shader-sources-size",
KIND_HEAP,
UNITS_BYTES,
WebGLMemoryReporter::GetShaderSourcesSize,
"Combined size of WebGL shader ASCII sources, cached on the heap. This should always be at most a few kilobytes, or dozen kilobytes for very shader-intensive WebGL demos.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderTranslationLogsSize,
"explicit/webgl/shader-translationlogs-size",
KIND_HEAP,
UNITS_BYTES,
WebGLMemoryReporter::GetShaderTranslationLogsSize,
"Combined size of WebGL shader ASCII translation logs, cached on the heap.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderCount,
"webgl-shader-count",
KIND_OTHER,
UNITS_COUNT,
WebGLMemoryReporter::GetShaderCount,
"Number of WebGL shaders.")
NS_MEMORY_REPORTER_IMPLEMENT(WebGLContextCount,
"webgl-context-count",
KIND_OTHER,
UNITS_COUNT,
WebGLMemoryReporter::GetContextCount,
"Number of WebGL contexts.")
WebGLMemoryReporter* WebGLMemoryReporter::UniqueInstance()
{
if (!sUniqueInstance) {
sUniqueInstance = new WebGLMemoryReporter;
}
return sUniqueInstance;
}
WebGLMemoryReporter::WebGLMemoryReporter()
: mTextureMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureMemoryUsed))
, mTextureCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureCount))
, mBufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferMemoryUsed))
, mBufferCacheMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCacheMemoryUsed))
, mBufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCount))
, mRenderbufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferMemoryUsed))
, mRenderbufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferCount))
, mShaderSourcesSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderSourcesSize))
, mShaderTranslationLogsSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderTranslationLogsSize))
, mShaderCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderCount))
, mContextCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLContextCount))
{
NS_RegisterMemoryReporter(mTextureMemoryUsageReporter);
NS_RegisterMemoryReporter(mTextureCountReporter);
NS_RegisterMemoryReporter(mBufferMemoryUsageReporter);
NS_RegisterMemoryReporter(mBufferCacheMemoryUsageReporter);
NS_RegisterMemoryReporter(mBufferCountReporter);
NS_RegisterMemoryReporter(mRenderbufferMemoryUsageReporter);
NS_RegisterMemoryReporter(mRenderbufferCountReporter);
NS_RegisterMemoryReporter(mShaderSourcesSizeReporter);
NS_RegisterMemoryReporter(mShaderTranslationLogsSizeReporter);
NS_RegisterMemoryReporter(mShaderCountReporter);
NS_RegisterMemoryReporter(mContextCountReporter);
}
WebGLMemoryReporter::~WebGLMemoryReporter()
{
NS_UnregisterMemoryReporter(mTextureMemoryUsageReporter);
NS_UnregisterMemoryReporter(mTextureCountReporter);
NS_UnregisterMemoryReporter(mBufferMemoryUsageReporter);
NS_UnregisterMemoryReporter(mBufferCacheMemoryUsageReporter);
NS_UnregisterMemoryReporter(mBufferCountReporter);
NS_UnregisterMemoryReporter(mRenderbufferMemoryUsageReporter);
NS_UnregisterMemoryReporter(mRenderbufferCountReporter);
NS_UnregisterMemoryReporter(mShaderSourcesSizeReporter);
NS_UnregisterMemoryReporter(mShaderTranslationLogsSizeReporter);
NS_UnregisterMemoryReporter(mShaderCountReporter);
NS_UnregisterMemoryReporter(mContextCountReporter);
}
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
@ -289,7 +162,7 @@ WebGLContext::WebGLContext()
mPixelStorePackAlignment = 4;
mPixelStoreUnpackAlignment = 4;
WebGLMemoryReporter::AddWebGLContext(this);
WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
mAllowRestore = true;
mRobustnessTimerRunning = false;
@ -303,7 +176,7 @@ WebGLContext::WebGLContext()
WebGLContext::~WebGLContext()
{
DestroyResourcesAndContext();
WebGLMemoryReporter::RemoveWebGLContext(this);
WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
TerminateRobustnessTimer();
mContextRestorer = nsnull;
}

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

@ -55,8 +55,8 @@
#include "nsHTMLCanvasElement.h"
#include "nsWeakReference.h"
#include "nsIDOMHTMLElement.h"
#include "nsIJSNativeInitializer.h"
#include "nsIMemoryReporter.h"
#include "nsIJSNativeInitializer.h"
#include "nsContentUtils.h"
#include "GLContextProvider.h"
@ -514,7 +514,7 @@ class WebGLContext :
public nsITimerCallback,
public WebGLRectangleObject
{
friend class WebGLMemoryReporter;
friend class WebGLMemoryMultiReporterWrapper;
friend class WebGLExtensionLoseContext;
friend class WebGLContextUserData;
@ -1055,6 +1055,10 @@ public:
mContext->mBuffers.RemoveElement(mMonotonicHandle);
}
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return aMallocSizeOf(this) + aMallocSizeOf(mData);
}
bool HasEverBeenBound() { return mHasEverBeenBound; }
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
GLuint GLName() const { return mGLName; }
@ -1627,6 +1631,12 @@ public:
~WebGLShader() {
DeleteOnce();
}
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) {
return aMallocSizeOf(this) +
mSource.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
mTranslationLog.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
void Delete() {
mSource.Truncate();
@ -2515,30 +2525,21 @@ WebGLContext::CanGetConcreteObject(const char *info,
return GetConcreteObject(info, aInterface, &aConcreteObject, isNull, isDeleted, false);
}
class WebGLMemoryReporter
class WebGLMemoryMultiReporterWrapper
{
WebGLMemoryReporter();
~WebGLMemoryReporter();
static WebGLMemoryReporter* sUniqueInstance;
WebGLMemoryMultiReporterWrapper();
~WebGLMemoryMultiReporterWrapper();
static WebGLMemoryMultiReporterWrapper* sUniqueInstance;
// here we store plain pointers, not RefPtrs: we don't want the WebGLMemoryReporter unique instance to keep alive all
// here we store plain pointers, not RefPtrs: we don't want the
// WebGLMemoryMultiReporterWrapper unique instance to keep alive all
// WebGLContexts ever created.
typedef nsTArray<const WebGLContext*> ContextsArrayType;
ContextsArrayType mContexts;
nsCOMPtr<nsIMemoryReporter> mTextureMemoryUsageReporter;
nsCOMPtr<nsIMemoryReporter> mTextureCountReporter;
nsCOMPtr<nsIMemoryReporter> mBufferMemoryUsageReporter;
nsCOMPtr<nsIMemoryReporter> mBufferCacheMemoryUsageReporter;
nsCOMPtr<nsIMemoryReporter> mBufferCountReporter;
nsCOMPtr<nsIMemoryReporter> mRenderbufferMemoryUsageReporter;
nsCOMPtr<nsIMemoryReporter> mRenderbufferCountReporter;
nsCOMPtr<nsIMemoryReporter> mShaderSourcesSizeReporter;
nsCOMPtr<nsIMemoryReporter> mShaderTranslationLogsSizeReporter;
nsCOMPtr<nsIMemoryReporter> mShaderCountReporter;
nsCOMPtr<nsIMemoryReporter> mContextCountReporter;
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
static WebGLMemoryReporter* UniqueInstance();
static WebGLMemoryMultiReporterWrapper* UniqueInstance();
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
@ -2552,7 +2553,7 @@ class WebGLMemoryReporter
ContextsArrayType & contexts = Contexts();
contexts.RemoveElement(c);
if (contexts.IsEmpty()) {
delete sUniqueInstance;
delete sUniqueInstance;
sUniqueInstance = nsnull;
}
}
@ -2561,8 +2562,8 @@ class WebGLMemoryReporter
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t t = 0; t < contexts[i]->mTextures.Length(); ++t)
result += contexts[i]->mTextures[t]->MemoryUsage();
for (size_t j = 0; j < contexts[i]->mTextures.Length(); ++j)
result += contexts[i]->mTextures[j]->MemoryUsage();
return result;
}
@ -2578,20 +2579,12 @@ class WebGLMemoryReporter
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t b = 0; b < contexts[i]->mBuffers.Length(); ++b)
result += contexts[i]->mBuffers[b]->ByteLength();
for (size_t j = 0; j < contexts[i]->mBuffers.Length(); ++j)
result += contexts[i]->mBuffers[j]->ByteLength();
return result;
}
static PRInt64 GetBufferCacheMemoryUsed() {
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t b = 0; b < contexts[i]->mBuffers.Length(); ++b)
if (contexts[i]->mBuffers[b]->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
result += contexts[i]->mBuffers[b]->ByteLength();
return result;
}
static PRInt64 GetBufferCacheMemoryUsed();
static PRInt64 GetBufferCount() {
const ContextsArrayType & contexts = Contexts();
@ -2605,8 +2598,8 @@ class WebGLMemoryReporter
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t r = 0; r < contexts[i]->mRenderbuffers.Length(); ++r)
result += contexts[i]->mRenderbuffers[r]->MemoryUsage();
for (size_t j = 0; j < contexts[i]->mRenderbuffers.Length(); ++j)
result += contexts[i]->mRenderbuffers[j]->MemoryUsage();
return result;
}
@ -2618,23 +2611,7 @@ class WebGLMemoryReporter
return result;
}
static PRInt64 GetShaderSourcesSize() {
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t s = 0; s < contexts[i]->mShaders.Length(); ++s)
result += contexts[i]->mShaders[s]->Source().Length();
return result;
}
static PRInt64 GetShaderTranslationLogsSize() {
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for(size_t i = 0; i < contexts.Length(); ++i)
for (size_t s = 0; s < contexts[i]->mShaders.Length(); ++s)
result += contexts[i]->mShaders[s]->TranslationLog().Length();
return result;
}
static PRInt64 GetShaderSize();
static PRInt64 GetShaderCount() {
const ContextsArrayType & contexts = Contexts();

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

@ -0,0 +1,218 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "WebGLContext.h"
#include "nsIMemoryReporter.h"
using namespace mozilla;
class WebGLMemoryMultiReporter : public nsIMemoryMultiReporter
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER
};
NS_IMPL_ISUPPORTS1(WebGLMemoryMultiReporter, nsIMemoryMultiReporter)
NS_IMETHODIMP
WebGLMemoryMultiReporter::GetName(nsACString &aName)
{
aName.AssignLiteral("webgl");
return NS_OK;
}
NS_IMETHODIMP
WebGLMemoryMultiReporter::GetExplicitNonHeap(PRInt64 *aAmount)
{
// WebGLMemoryMultiReporterWrapper has no KIND_NONHEAP measurements.
*aAmount = 0;
return NS_OK;
}
NS_IMETHODIMP
WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
nsISupports* aClosure)
{
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-texture-memory"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetTextureMemoryUsed(),
NS_LITERAL_CSTRING("Memory used by WebGL textures.The OpenGL"
" implementation is free to store these textures in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-texture-count"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetTextureCount(),
NS_LITERAL_CSTRING("Number of WebGL textures."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-buffer-memory"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetBufferMemoryUsed(),
NS_LITERAL_CSTRING("Memory used by WebGL buffers. The OpenGL"
" implementation is free to store these buffers in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("explicit/webgl/buffer-cache-memory"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed(),
NS_LITERAL_CSTRING("Memory used by WebGL buffer caches. The WebGL"
" implementation caches the contents of element array buffers"
" only.This adds up with the webgl-buffer-memory value, but"
" contrary to it, this one represents bytes on the heap,"
" not managed by OpenGL."),
aClosure);
aCb->Callback(
EmptyCString(), NS_LITERAL_CSTRING("webgl-buffer-count"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetBufferCount(),
NS_LITERAL_CSTRING("Number of WebGL buffers."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-renderbuffer-memory"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetRenderbufferMemoryUsed(),
NS_LITERAL_CSTRING("Memory used by WebGL renderbuffers. The OpenGL"
" implementation is free to store these renderbuffers in either"
" video memory or main memory. This measurement is only a lower"
" bound, actual memory usage may be higher for example if the"
" storage is strided."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-renderbuffer-count"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetRenderbufferCount(),
NS_LITERAL_CSTRING("Number of WebGL renderbuffers."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("explicit/webgl/shader"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetShaderSize(),
NS_LITERAL_CSTRING("Combined size of WebGL shader ASCII sources and"
" translation logs cached on the heap."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-shader-count"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetShaderCount(),
NS_LITERAL_CSTRING("Number of WebGL shaders."),
aClosure);
aCb->Callback(
EmptyCString(),
NS_LITERAL_CSTRING("webgl-context-count"),
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetContextCount(),
NS_LITERAL_CSTRING("Number of WebGL contexts."),
aClosure);
return NS_OK;
}
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::sUniqueInstance = nsnull;
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::UniqueInstance()
{
if (!sUniqueInstance) {
sUniqueInstance = new WebGLMemoryMultiReporterWrapper;
}
return sUniqueInstance;
}
WebGLMemoryMultiReporterWrapper::WebGLMemoryMultiReporterWrapper()
{
mReporter = new WebGLMemoryMultiReporter;
NS_RegisterMemoryMultiReporter(mReporter);
}
WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
{
NS_UnregisterMemoryMultiReporter(mReporter);
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOfFun, "webgl-buffer")
PRInt64
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for (size_t i = 0; i < contexts.Length(); ++i) {
for (size_t j = 0; j < contexts[i]->mBuffers.Length(); ++j)
if (contexts[i]->mBuffers[j]->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
result += contexts[i]->mBuffers[j]->SizeOfIncludingThis(WebGLBufferMallocSizeOfFun);
}
return result;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOfFun, "webgl-shader")
PRInt64
WebGLMemoryMultiReporterWrapper::GetShaderSize() {
const ContextsArrayType & contexts = Contexts();
PRInt64 result = 0;
for (size_t i = 0; i < contexts.Length(); ++i) {
for (size_t j = 0; j < contexts[i]->mShaders.Length(); ++j)
result += contexts[i]->mShaders[j]->SizeOfIncludingThis(WebGLShaderMallocSizeOfFun);
}
return result;
}

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

@ -1292,26 +1292,24 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
mWidth = width;
mHeight = height;
mTarget = target;
// This first time this is called on this object is via
// nsHTMLCanvasElement::GetContext. If target was non-null then mTarget is
// non-null, otherwise we'll return an error here and GetContext won't
// return this context object and we'll never enter this code again.
// All other times this method is called, if target is null then
// mTarget won't be changed, i.e. it will remain non-null, or else it
// will be set to non-null.
// In all cases, any usable canvas context will have non-null mTarget.
if (target) {
mValid = true;
mTarget = target;
} else {
mValid = false;
}
mResetLayer = true;
/* Create dummy surfaces here - target can be null when a canvas was created
* that is too large to support.
*/
if (!target)
{
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
if (!mTarget) {
// SupportsAzure() is controlled by the "gfx.canvas.azure.prefer-skia"
// pref so that may be the reason rather than an OOM.
mValid = false;
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
mValid = true;
}
// set up the initial canvas defaults
mStyleStack.Clear();
mPathBuilder = nsnull;
@ -1325,11 +1323,12 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
state->shadowColor = NS_RGBA(0,0,0,0);
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
if (mTarget) {
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
}
return mValid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}

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

@ -180,8 +180,7 @@ nsDOMEvent::InitPresContextData(nsPresContext* aPresContext)
// Get the explicit original target (if it's anonymous make it null)
{
nsCOMPtr<nsIContent> content = GetTargetFromFrame();
mTmpRealOriginalTarget = do_QueryInterface(content);
mExplicitOriginalTarget = mTmpRealOriginalTarget;
mExplicitOriginalTarget = do_QueryInterface(content);
if (content && content->IsInAnonymousSubtree()) {
mExplicitOriginalTarget = nsnull;
}
@ -237,10 +236,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPresContext);
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTmpRealOriginalTarget)
// Always set mExplicitOriginalTarget to null, when
// mTmpRealOriginalTarget doesn't point to any object!
tmp->mExplicitOriginalTarget = nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExplicitOriginalTarget);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
@ -275,7 +271,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mPresContext.get(), nsPresContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTmpRealOriginalTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mExplicitOriginalTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
// nsIDOMEventInterface
@ -355,18 +351,6 @@ nsDOMEvent::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
return GetTarget(aRealEventTarget);
}
NS_IMETHODIMP
nsDOMEvent::GetTmpRealOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
{
if (mTmpRealOriginalTarget) {
*aRealEventTarget = mTmpRealOriginalTarget;
NS_ADDREF(*aRealEventTarget);
return NS_OK;
}
return GetOriginalTarget(aRealEventTarget);
}
NS_IMETHODIMP
nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
{

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

@ -267,8 +267,7 @@ protected:
nsEvent* mEvent;
nsRefPtr<nsPresContext> mPresContext;
nsCOMPtr<nsIDOMEventTarget> mTmpRealOriginalTarget;
nsIDOMEventTarget* mExplicitOriginalTarget;
nsCOMPtr<nsIDOMEventTarget> mExplicitOriginalTarget;
nsString mCachedType;
bool mEventIsInternal;
bool mPrivateDataDuplicated;

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

@ -2081,14 +2081,12 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
if (!dataTransfer)
return;
bool isInEditor = false;
bool isSelection = false;
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsIContent> eventContent, targetContent;
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
if (eventContent)
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
&isSelection, &isInEditor,
getter_AddRefs(targetContent));
getter_AddRefs(selection), getter_AddRefs(targetContent));
// Stop tracking the drag gesture now. This should stop us from
// reentering GenerateDragGesture inside DOM event processing.
@ -2129,9 +2127,8 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
// elements in an editor, only fire the draggesture event so that the
// editor code can handle it but content doesn't see a dragstart.
nsEventStatus status = nsEventStatus_eIgnore;
if (!isInEditor)
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
&status);
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
&status);
nsDragEvent* event = &startEvent;
if (status != nsEventStatus_eConsumeNoDefault) {
@ -2148,7 +2145,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
if (status != nsEventStatus_eConsumeNoDefault) {
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
targetContent, isSelection);
targetContent, selection);
if (dragStarted) {
sActiveESM = nsnull;
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
@ -2173,37 +2170,27 @@ void
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* aSelectionTarget,
nsDOMDataTransfer* aDataTransfer,
bool* aIsSelection,
bool* aIsInEditor,
nsISelection** aSelection,
nsIContent** aTargetNode)
{
*aTargetNode = nsnull;
*aIsInEditor = false;
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
// GetDragData determines if a selection, link or image in the content
// should be dragged, and places the data associated with the drag in the
// data transfer. Skip this check for chrome shells.
// data transfer.
// mGestureDownContent is the node where the mousedown event for the drag
// occurred, and aSelectionTarget is the node to use when a selection is used
bool canDrag;
nsCOMPtr<nsIContent> dragDataNode;
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
if (dsti) {
PRInt32 type = -1;
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
type != nsIDocShellTreeItem::typeChrome) {
// mGestureDownContent is the node where the mousedown event for the drag
// occurred, and aSelectionTarget is the node to use when a selection is used
nsresult rv =
nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
aSelectionTarget, mGestureDownAlt,
aDataTransfer, &canDrag, aIsSelection,
getter_AddRefs(dragDataNode));
if (NS_FAILED(rv) || !canDrag)
return;
}
}
nsresult rv = nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
aSelectionTarget, mGestureDownAlt,
aDataTransfer, &canDrag, aSelection,
getter_AddRefs(dragDataNode));
if (NS_FAILED(rv) || !canDrag)
return;
// if GetDragData returned a node, use that as the node being dragged.
// Otherwise, if a selection is being dragged, use the node within the
@ -2211,7 +2198,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* dragContent = mGestureDownContent;
if (dragDataNode)
dragContent = dragDataNode;
else if (*aIsSelection)
else if (*aSelection)
dragContent = aSelectionTarget;
nsIContent* originalDragContent = dragContent;
@ -2220,7 +2207,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
// draggable property set. If one is found, use that as the target of the
// drag instead of the node that was clicked on. If a draggable node wasn't
// found, just use the clicked node.
if (!*aIsSelection) {
if (!*aSelection) {
while (dragContent) {
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(dragContent);
if (htmlElement) {
@ -2245,17 +2232,6 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
// otherwise, it's not an HTML or XUL element, so just keep looking
}
dragContent = dragContent->GetParent();
// if an editable parent is encountered, then we don't look at any
// ancestors. This is used because the editor attaches a draggesture
// listener to the editable element and we want to call it without
// making the editable element draggable. This should be removed once
// the editor is switched over to using the proper drag and drop api.
nsCOMPtr<nsIDOMNSEditableElement> editableElement = do_QueryInterface(dragContent);
if (editableElement) {
*aIsInEditor = true;
break;
}
}
}
@ -2279,7 +2255,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
nsDragEvent* aDragEvent,
nsDOMDataTransfer* aDataTransfer,
nsIContent* aDragTarget,
bool aIsSelection)
nsISelection* aSelection)
{
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
@ -2333,22 +2309,6 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
PRInt32 imageX, imageY;
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
// If a selection is being dragged, and no custom drag image was
// set, get the selection so that the drag region can be created
// from the selection area. If a custom image was set, it doesn't
// matter what the selection is since the image will be used instead.
nsISelection* selection = nsnull;
if (aIsSelection && !dragImage) {
nsIDocument* doc = aDragTarget->GetCurrentDoc();
if (doc) {
nsIPresShell* presShell = doc->GetShell();
if (presShell) {
selection = presShell->GetCurrentSelection(
nsISelectionController::SELECTION_NORMAL);
}
}
}
nsCOMPtr<nsISupportsArray> transArray;
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
if (!transArray)
@ -2363,8 +2323,13 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
// if creating a drag event failed, starting a drag session will
// just fail.
if (selection) {
dragService->InvokeDragSessionWithSelection(selection, transArray,
// Use InvokeDragSessionWithSelection if a selection is being dragged,
// such that the image can be generated from the selected text. However,
// use InvokeDragSessionWithImage if a custom image was set or something
// other than a selection is being dragged.
if (!dragImage && aSelection) {
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
action, domDragEvent,
aDataTransfer);
}

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

@ -417,15 +417,13 @@ protected:
*
* aSelectionTarget - target to check for selection
* aDataTransfer - data transfer object that will contain the data to drag
* aIsSelection - [out] set to true if a selection is being dragged
* aIsInEditor - [out] set to true if the content is in an editor field
* aSelection - [out] set to the selection to be dragged
* aTargetNode - [out] the draggable node, or null if there isn't one
*/
void DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* aSelectionTarget,
nsDOMDataTransfer* aDataTransfer,
bool* aIsSelection,
bool* aIsInEditor,
nsISelection** aSelection,
nsIContent** aTargetNode);
/*
@ -436,13 +434,13 @@ protected:
* aDragEvent - the dragstart/draggesture event
* aDataTransfer - the data transfer that holds the data to be dragged
* aDragTarget - the target of the drag
* aIsSelection - true if a selection is being dragged
* aSelection - the selection to be dragged
*/
bool DoDefaultDragStart(nsPresContext* aPresContext,
nsDragEvent* aDragEvent,
nsDOMDataTransfer* aDataTransfer,
nsIContent* aDragTarget,
bool aIsSelection);
nsISelection* aSelection);
bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
/**

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

@ -456,6 +456,12 @@ protected:
*/
void SelectResource();
/**
* A wrapper function that allows us to cleanly reset flags after a call
* to SelectResource()
*/
void SelectResourceWrapper();
/**
* Asynchronously awaits a stable state, and then causes SelectResource()
* to be run on the main thread's event loop.
@ -739,6 +745,9 @@ protected:
// or while we're running SelectResource().
bool mIsRunningSelectResource;
// True when we already have select resource call queued
bool mHaveQueuedSelectResource;
// True if we suspended the decoder because we were paused,
// preloading metadata is enabled, autoplay was not enabled, and we loaded
// the first frame.

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

@ -538,6 +538,7 @@ void nsHTMLMediaElement::AbortExistingLoads()
mIsLoadingFromSourceChildren = false;
mSuspendedAfterFirstFrame = false;
mAllowSuspendAfterFirstFrame = true;
mHaveQueuedSelectResource = false;
mLoadIsSuspended = false;
mSourcePointer = nsnull;
@ -625,11 +626,11 @@ void nsHTMLMediaElement::QueueLoadFromSourceTask()
void nsHTMLMediaElement::QueueSelectResourceTask()
{
// Don't allow multiple async select resource calls to be queued.
if (mIsRunningSelectResource)
if (mHaveQueuedSelectResource)
return;
mIsRunningSelectResource = true;
mHaveQueuedSelectResource = true;
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
AsyncAwaitStableState(this, &nsHTMLMediaElement::SelectResource);
AsyncAwaitStableState(this, &nsHTMLMediaElement::SelectResourceWrapper);
}
/* void load (); */
@ -658,6 +659,13 @@ static bool HasSourceChildren(nsIContent *aElement)
return false;
}
void nsHTMLMediaElement::SelectResourceWrapper()
{
SelectResource();
mIsRunningSelectResource = false;
mHaveQueuedSelectResource = false;
}
void nsHTMLMediaElement::SelectResource()
{
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::src) && !HasSourceChildren(this)) {
@ -666,7 +674,6 @@ void nsHTMLMediaElement::SelectResource()
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
ChangeDelayLoadStatus(false);
mIsRunningSelectResource = false;
return;
}
@ -677,6 +684,12 @@ void nsHTMLMediaElement::SelectResource()
// AddRemoveSelfReference, since it must still be held
DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
// Delay setting mIsRunningSeletResource until after UpdatePreloadAction
// so that we don't lose our state change by bailing out of the preload
// state update
UpdatePreloadAction();
mIsRunningSelectResource = true;
// If we have a 'src' attribute, use that exclusively.
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
@ -691,13 +704,11 @@ void nsHTMLMediaElement::SelectResource()
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();
mIsRunningSelectResource = false;
return;
}
rv = LoadResource();
if (NS_SUCCEEDED(rv)) {
mIsRunningSelectResource = false;
return;
}
} else {
@ -710,7 +721,6 @@ void nsHTMLMediaElement::SelectResource()
mIsLoadingFromSourceChildren = true;
LoadFromSourceChildren();
}
mIsRunningSelectResource = false;
}
void nsHTMLMediaElement::NotifyLoadError()
@ -1441,6 +1451,7 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mIsLoadingFromSourceChildren(false),
mDelayingLoadEvent(false),
mIsRunningSelectResource(false),
mHaveQueuedSelectResource(false),
mSuspendedAfterFirstFrame(false),
mAllowSuspendAfterFirstFrame(true),
mHasPlayedOrSeeked(false),

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

@ -901,7 +901,7 @@ nsHTMLTableElement::ParseAttribute(PRInt32 aNamespaceID,
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::cellspacing ||
aAttribute == nsGkAtoms::cellpadding) {
return aResult.ParseSpecialIntValue(aValue);
return aResult.ParseNonNegativeIntValue(aValue);
}
if (aAttribute == nsGkAtoms::cols ||
aAttribute == nsGkAtoms::border) {
@ -971,19 +971,10 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
// cellspacing
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
nsCSSValue* borderSpacing = aData->ValueForBorderSpacing();
if (value && value->Type() == nsAttrValue::eInteger) {
if (borderSpacing->GetUnit() == eCSSUnit_Null) {
borderSpacing->
SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
}
else if (value && value->Type() == nsAttrValue::ePercent &&
eCompatibility_NavQuirks == mode) {
// in quirks mode, treat a % cellspacing value a pixel value.
if (borderSpacing->GetUnit() == eCSSUnit_Null) {
borderSpacing->
SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
}
if (value && value->Type() == nsAttrValue::eInteger &&
borderSpacing->GetUnit() == eCSSUnit_Null) {
borderSpacing->
SetFloatValue(float(value->GetIntegerValue()), eCSSUnit_Pixel);
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Table)) {
@ -1159,39 +1150,29 @@ MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes,
{
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Padding)) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellpadding);
if (value) {
nsAttrValue::ValueType valueType = value->Type();
if (valueType == nsAttrValue::eInteger ||
valueType == nsAttrValue::ePercent) {
// We have cellpadding. This will override our padding values if we
// don't have any set.
nsCSSValue padVal;
if (valueType == nsAttrValue::eInteger)
padVal.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else {
// when we support % cellpadding in standard mode, uncomment the
// following
float pctVal = value->GetPercentValue();
//if (eCompatibility_NavQuirks == mode) {
// in quirks mode treat a pct cellpadding value as a pixel value
padVal.SetFloatValue(100.0f * pctVal, eCSSUnit_Pixel);
//}
//else {
// padVal.SetPercentValue(pctVal);
//}
}
nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue();
if (paddingLeft->GetUnit() == eCSSUnit_Null)
*paddingLeft = padVal;
nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
if (paddingRight->GetUnit() == eCSSUnit_Null)
*paddingRight = padVal;
nsCSSValue* paddingTop = aData->ValueForPaddingTop();
if (paddingTop->GetUnit() == eCSSUnit_Null)
*paddingTop = padVal;
nsCSSValue* paddingBottom = aData->ValueForPaddingBottom();
if (paddingBottom->GetUnit() == eCSSUnit_Null)
*paddingBottom = padVal;
if (value && value->Type() == nsAttrValue::eInteger) {
// We have cellpadding. This will override our padding values if we
// don't have any set.
nsCSSValue padVal(float(value->GetIntegerValue()), eCSSUnit_Pixel);
nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue();
if (paddingLeft->GetUnit() == eCSSUnit_Null) {
*paddingLeft = padVal;
}
nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
if (paddingRight->GetUnit() == eCSSUnit_Null) {
*paddingRight = padVal;
}
nsCSSValue* paddingTop = aData->ValueForPaddingTop();
if (paddingTop->GetUnit() == eCSSUnit_Null) {
*paddingTop = padVal;
}
nsCSSValue* paddingBottom = aData->ValueForPaddingBottom();
if (paddingBottom->GetUnit() == eCSSUnit_Null) {
*paddingBottom = padVal;
}
}
}

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

@ -70,6 +70,12 @@ function nextTest() {
}
}
try {
window.fullScreen = true;
} catch (e) {
}
is(window.fullScreen, false, "Shouldn't be able to set window fullscreen from content");
addLoadEvent(nextTest);
SimpleTest.waitForExplicitFinish();

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

@ -327,7 +327,9 @@ nsresult nsBuiltinDecoder::Seek(double aTime)
PRInt32 range = 0;
if (!IsInRanges(seekable, aTime, range)) {
if (range != -1) {
if (range + 1 < length) {
// |range + 1| can't be negative, because the only possible negative value
// for |range| is -1.
if (PRUint32(range + 1) < length) {
double leftBound, rightBound;
res = seekable.End(range, &leftBound);
NS_ENSURE_SUCCESS(res, NS_OK);

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

@ -49,6 +49,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/StdInt.h"
#include "mozilla/Util.h"
using namespace mozilla;
using namespace mozilla::layers;
@ -307,9 +308,8 @@ void StateMachineTracker::EnsureGlobalStateMachine()
ReentrantMonitorAutoEnter mon(mMonitor);
if (mStateMachineCount == 0) {
NS_ASSERTION(!mStateMachineThread, "Should have null state machine thread!");
nsresult res = NS_NewThread(&mStateMachineThread,
nsnull);
NS_ABORT_IF_FALSE(NS_SUCCEEDED(res), "Can't create media state machine thread");
DebugOnly<nsresult> rv = NS_NewThread(&mStateMachineThread, nsnull);
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Can't create media state machine thread");
}
mStateMachineCount++;
}

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