This commit is contained in:
Brendan Eich 2008-06-05 14:55:05 -07:00
Родитель cd32263a49 9704ef1a8b
Коммит f86a783ddf
37 изменённых файлов: 525 добавлений и 228 удалений

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

@ -85,7 +85,8 @@ nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
//-----------------------------------------------------
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE), mIsLoadCompleteFired(PR_FALSE)
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE),
mIsLoadCompleteFired(PR_FALSE), mInFlushPendingEvents(PR_FALSE)
{
// For GTK+ native window, we do nothing here.
if (!mDOMNode)
@ -589,7 +590,10 @@ NS_IMETHODIMP nsDocAccessible::Shutdown()
mEventsToFire.Clear();
// Make sure we release the kung fu death grip which is always
// there when there are still events left to be fired
NS_RELEASE_THIS();
// If FlushPendingEvents() is in call stack,
// kung fu death grip will be released there.
if (!mInFlushPendingEvents)
NS_RELEASE_THIS();
}
}
@ -1505,6 +1509,7 @@ nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
{
mInFlushPendingEvents = PR_TRUE;
PRUint32 length = mEventsToFire.Count();
NS_ASSERTION(length, "How did we get here without events to fire?");
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
@ -1625,7 +1630,8 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
#endif
nsCOMPtr<nsIAccessibleCaretMoveEvent> caretMoveEvent =
new nsAccCaretMoveEvent(accessible, caretOffset);
NS_ENSURE_TRUE(caretMoveEvent, NS_ERROR_OUT_OF_MEMORY);
if (!caretMoveEvent)
break; // Out of memory, break out to release kung fu death grip
FireAccessibleEvent(caretMoveEvent);
@ -1661,6 +1667,7 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
// After a flood of events, reset so that user input flag is off
nsAccEvent::ResetLastInputState();
mInFlushPendingEvents = PR_FALSE;
return NS_OK;
}

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

@ -221,6 +221,7 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
protected:
PRBool mIsAnchor;
PRBool mIsAnchorJumped;
PRBool mInFlushPendingEvents;
static PRUint32 gLastFocusedAccessiblesState;
static nsIAtom *gLastFocusedFrameType;
};

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

@ -4255,6 +4255,18 @@ MOZ_ARG_WITH_STRING(java-bin-path,
[ --with-java-bin-path=dir Location of Java binaries (java, javac, jar)],
JAVA_BIN_PATH=$withval)
dnl ========================================================
dnl Use ARM userspace kernel helpers; tell NSPR to enable
dnl their usage and use them in spidermonkey.
dnl ========================================================
MOZ_ARG_WITH_BOOL(arm-kuser,
[ --with-arm-kuser Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
USE_ARM_KUSER=1,
USE_ARM_KUSER=)
if test -n "$USE_ARM_KUSER"; then
AC_DEFINE(USE_ARM_KUSER)
fi
dnl ========================================================
dnl =
dnl = Application
@ -8264,6 +8276,9 @@ if test -z "$MOZ_NATIVE_NSPR" || test "$MOZ_LDAP_XPCOM"; then
if test -n "$HAVE_64BIT_OS"; then
ac_configure_args="$ac_configure_args --enable-64bit"
fi
if test -n "$USE_ARM_KUSER"; then
ac_configure_args="$ac_configure_args --with-arm-kuser"
fi
AC_OUTPUT_SUBDIRS(nsprpub)
ac_configure_args="$_SUBDIR_CONFIG_ARGS"
fi

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

@ -397,6 +397,7 @@ GK_ATOM(i, "i")
GK_ATOM(id, "id")
GK_ATOM(_if, "if")
GK_ATOM(iframe, "iframe")
GK_ATOM(ignore, "ignore")
GK_ATOM(ignorecase, "ignorecase")
GK_ATOM(ignorekeys, "ignorekeys")
GK_ATOM(ilayer, "ilayer")
@ -802,6 +803,7 @@ GK_ATOM(staticHint, "staticHint")
GK_ATOM(statustext, "statustext")
GK_ATOM(stop, "stop")
GK_ATOM(stretch, "stretch")
GK_ATOM(stretch_to_fit, "stretch-to-fit")
GK_ATOM(strike, "strike")
GK_ATOM(string, "string")
GK_ATOM(stringLength, "string-length")

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

@ -3877,19 +3877,21 @@ nsHTMLDocument::GetDocumentAllResult(const nsAString& aID, nsISupports** aResult
NS_ENSURE_TRUE(entry->mDocAllList, NS_ERROR_OUT_OF_MEMORY);
}
nsRefPtr<nsContentList> docAllList = entry->mDocAllList;
// Check if there are more than 1 entries. Do this by getting the second one
// rather than the length since getting the length always requires walking
// the entire document.
nsIContent* cont = entry->mDocAllList->Item(1, PR_TRUE);
nsIContent* cont = docAllList->Item(1, PR_TRUE);
if (cont) {
NS_ADDREF(*aResult = static_cast<nsIDOMNodeList*>(entry->mDocAllList));
NS_ADDREF(*aResult = static_cast<nsIDOMNodeList*>(docAllList));
return NS_OK;
}
// There's only 0 or 1 items. Return the first one or null.
NS_IF_ADDREF(*aResult = entry->mDocAllList->Item(0, PR_TRUE));
NS_IF_ADDREF(*aResult = docAllList->Item(0, PR_TRUE));
return NS_OK;
}

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

@ -152,6 +152,8 @@
#include "nsEventDispatcher.h"
#include "nsPresShellIterator.h"
#include "mozAutoDocUpdate.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIDOMNSEvent.h"
/**
* Three bits are used for XUL Element's lazy state.
@ -1648,6 +1650,22 @@ nsXULElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
EmptyString(),
&aVisitor.mDOMEvent);
}
nsCOMPtr<nsIDOMNSEvent> nsevent =
do_QueryInterface(aVisitor.mDOMEvent);
while (nsevent) {
nsCOMPtr<nsIDOMEventTarget> oTarget;
nsevent->GetOriginalTarget(getter_AddRefs(oTarget));
NS_ENSURE_STATE(!SameCOMIdentity(oTarget, commandContent));
nsCOMPtr<nsIDOMEvent> tmp;
nsCOMPtr<nsIDOMXULCommandEvent> commandEvent =
do_QueryInterface(nsevent);
if (commandEvent) {
commandEvent->GetSourceEvent(getter_AddRefs(tmp));
}
nsevent = do_QueryInterface(tmp);
}
event.sourceEvent = aVisitor.mDOMEvent;
nsEventStatus status = nsEventStatus_eIgnore;

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

@ -406,7 +406,7 @@ interface nsIDOMCSS2Properties : nsISupports
// raises(DOMException) on setting
};
[scriptable, uuid(c9339b8c-9bdd-4d2a-a61a-55ca609b92bd)]
[scriptable, uuid(8a5b178d-c805-4f8e-8992-fa7c5c11d08e)]
interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties
{
/* Non-DOM 2 extensions */
@ -591,4 +591,6 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties
attribute DOMString MozBorderStartWidth;
// raises(DOMException) on setting
attribute DOMString MozStackSizing;
// raises(DOMException) on setting
};

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

@ -0,0 +1,22 @@
// Tests conversion of a single byte from UTF-16 to Unicode
const inString = "A";
const expectedString = "\ufffd";
const charset = "UTF-16BE";
function run_test() {
var ScriptableUnicodeConverter =
Components.Constructor("@mozilla.org/intl/scriptableunicodeconverter",
"nsIScriptableUnicodeConverter");
var converter = new ScriptableUnicodeConverter();
converter.charset = charset;
try {
var outString = converter.ConvertToUnicode(inString) + converter.Finish();
} catch(e) {
outString = "\ufffd";
}
do_check_eq(outString, expectedString);
}

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

@ -0,0 +1,53 @@
// Tests encoding of characters below U+0020
const Ci = Components.interfaces;
const Cc = Components.classes;
const inString = "Hello\u000aWorld";
const expectedString = "Hello\nWorld";
function run_test() {
var failures = false;
var ccManager = Cc["@mozilla.org/charset-converter-manager;1"]
.getService(Ci.nsICharsetConverterManager);
var encodingConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
var charsetList = ccManager.getDecoderList();
var counter = 0;
while (charsetList.hasMore()) {
++counter;
var charset = charsetList.getNext();
// exclude known non-ASCII compatible charsets
if (charset.substr(0, "UTF-16".length) == "UTF-16" ||
charset.substr(0, "UTF-32".length) == "UTF-32" ||
charset == "x-imap4-modified-utf7") {
dump("skipping " + counter + " " + charset + "\n");
continue;
}
dump("testing " + counter + " " + charset + "\n");
try {
encodingConverter.charset = charset;
} catch(e) {
dump("Warning: couldn't set encoder charset to " + charset + "\n");
continue;
}
var codepageString = encodingConverter.ConvertFromUnicode(inString) +
encodingConverter.Finish();
if (codepageString != expectedString) {
dump(charset + " encoding failed\n");
for (var i = 0; i < expectedString.length; ++i) {
if (codepageString.charAt(i) != expectedString.charAt(i)) {
dump(i.toString(16) + ": 0x" +
codepageString.charCodeAt(i).toString(16) + " != " +
expectedString.charCodeAt(i).toString(16) + "\n");
}
}
failures = true;
}
}
if (failures) {
do_throw("test failed\n");
}
}

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

@ -59,11 +59,13 @@ UTF16ConvertToUnicode(PRUint8& aState, PRUint8& aData, const char * aSrc,
if(STATE_FOUND_BOM == aState) // caller found a BOM
{
NS_ASSERTION(*aSrcLength >= 2, "Too few bytes in input");
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
src+=2;
aState = STATE_NORMAL;
} else if(STATE_FIRST_CALL == aState) { // first time called
NS_ASSERTION(*aSrcLength >= 2, "Too few bytes in input");
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
// Eliminate BOM (0xFEFF). Note that different endian case is taken care of
// in |Convert| of LE and BE converters. Here, we only have to
@ -159,7 +161,8 @@ nsUTF16BEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
if(STATE_FIRST_CALL == mState) // Called for the first time.
{
mState = STATE_NORMAL;
NS_ASSERTION(*aSrcLength >= 2, "Too few bytes in input");
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
if(0xFFFE == *((PRUnichar*)aSrc)) {
// eliminate BOM (on LE machines, BE BOM is 0xFFFE)
mState = STATE_FOUND_BOM;
@ -190,7 +193,8 @@ nsUTF16LEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
if(STATE_FIRST_CALL == mState) // first time called
{
mState = STATE_NORMAL;
NS_ASSERTION(*aSrcLength >= 2, "Too few bytes in input");
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
if(0xFFFE == *((PRUnichar*)aSrc)) {
// eliminate BOM (on BE machines, LE BOM is 0xFFFE)
mState = STATE_FOUND_BOM;
@ -226,7 +230,8 @@ nsUTF16ToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
if(STATE_FIRST_CALL == mState) // first time called
{
mState = STATE_NORMAL;
NS_ASSERTION(*aSrcLength >= 2, "Too few bytes in input");
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
// check if BOM (0xFEFF) is at the beginning, remove it if found, and
// set mEndian accordingly.

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

@ -62,8 +62,13 @@ nsresult nsUnicodeEncodeHelper::ConvertByTable(
while (src < srcEnd) {
if (!uMapCode((uTable*) aMappingTable, static_cast<PRUnichar>(*(src++)), reinterpret_cast<PRUint16*>(&med))) {
res = NS_ERROR_UENC_NOMAPPING;
break;
if (*(src - 1) < 0x20) {
// some tables are missing the 0x00 - 0x20 part
med = *(src - 1);
} else {
res = NS_ERROR_UENC_NOMAPPING;
break;
}
}
PRBool charFound;

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

@ -178,6 +178,24 @@ js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
return !_check_lock((atomic_p)w, ov, nv);
}
#elif defined(USE_ARM_KUSER)
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=429387 for a
* description of this ABI; this is a function provided at a fixed
* location by the kernel in the memory space of each process.
*/
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
JS_STATIC_ASSERT(sizeof(jsword) == sizeof(int));
static JS_INLINE int
js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
{
volatile int *vp = (volatile int*)w;
return !__kernel_cmpxchg(ov, nv, vp);
}
#else
#error "Define NSPR_LOCK if your platform lacks a compare-and-swap instruction."

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

@ -226,7 +226,7 @@ extern void js_SetScopeInfo(JSScope *scope, const char *file, int line);
!( (defined(_WIN32) && defined(_M_IX86)) || \
(defined(__GNUC__) && defined(__i386__)) || \
(defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \
defined(AIX) )
defined(AIX) || defined(USE_ARM_KUSER))
#define NSPR_LOCK 1

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

@ -128,6 +128,10 @@
#define NS_STYLE_BOX_ORIENT_HORIZONTAL 0
#define NS_STYLE_BOX_ORIENT_VERTICAL 1
// stack-sizing
#define NS_STYLE_STACK_SIZING_IGNORE 0
#define NS_STYLE_STACK_SIZING_STRETCH_TO_FIT 1
// Azimuth - See nsStyleAural
#define NS_STYLE_AZIMUTH_LEFT_SIDE 0x00
#define NS_STYLE_AZIMUTH_FAR_LEFT 0x01

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

@ -0,0 +1,56 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3c.org/1999/xhtml"
width="400"
height="600">
<vbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 100px; background: blue;"/>
<spacer style="width: 50px; background: yellow;"/>
<spacer style="width: 150px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 100px; background: blue;"/>
<spacer style="width: 50px; background: yellow;"/>
<spacer style="width: 150px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 100px; background: blue;"/>
<spacer style="width: 50px; background: yellow;"/>
<spacer style="width: 150px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 100px; background: blue;"/>
<spacer style="width: 200px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 300px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 200px; background: yellow;"/>
<spacer style="width: 200px; background: green;"/>
</hbox>
<hbox style="height: 20px;">
<spacer style="width: 100px; background: yellow;"/>
<spacer style="width: 300px; background: green;"/>
</hbox>
</vbox>
</window>

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

@ -0,0 +1,71 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3c.org/1999/xhtml"
width="400"
height="600">
<vbox style="max-width: 400px;">
<!-- default: the inner hbox should expand the stack. -->
<hbox style="height: 20px;">
<stack flex="1" style="background: yellow;">
<hbox style="width: 100px; height: 20px; background: blue;" top="0" left="100"/>
</stack>
<spacer flex="3" style="background: green;"/>
</hbox>
<!-- same as above, with explicit -moz-stack-sizing: stretch-to-fit -->
<hbox style="height: 20px;">
<stack flex="1" style="background: yellow;">
<hbox style="-moz-stack-sizing: stretch-to-fit; width: 100px; height: 20px; background: blue;" top="0" left="100"/>
</stack>
<spacer flex="3" style="background: green;"/>
</hbox>
<!-- same as above, but with overflow: hidden -->
<hbox style="height: 20px;">
<stack flex="1" style="overflow: hidden; background: yellow;">
<hbox style="-moz-stack-sizing: stretch-to-fit; width: 100px; height: 20px; background: blue;" top="0" left="100"/>
</stack>
<spacer flex="3" style="background: green; height: 20px;"/>
</hbox>
<!-- inner hbox has stack-sizing: ignore, but the stack doesn't have overflow: hidden set; the stack will stretch
just enough to include the child, but no more -->
<hbox style="height: 20px;">
<stack flex="1" style="background: yellow;">
<hbox style="-moz-stack-sizing: ignore; width: 100px; height: 20px; background: blue;" top="0" left="100"/>
</stack>
<spacer flex="3" style="background: green; height: 20px;"/>
</hbox>
<!-- same as above, except stack has overflow: hidden set, so the blue shouldn't be visible -->
<hbox style="height: 20px;">
<stack flex="1" style="overflow: hidden; background: yellow;">
<hbox style="-moz-stack-sizing: ignore; width: 100px; height: 20px; background: blue;" top="0" left="100"/>
</stack>
<spacer flex="3" style="background: green; height: 20px;"/>
</hbox>
<!-- no flex on the stack, but an explicit size; the child will cause us to resize the stack during Layout -->
<hbox style="height: 20px;">
<stack style="width: 100px; background: yellow;">
<hbox style="width: 100px; height: 20px; background: transparent;" top="0" left="100"/>
</stack>
<spacer flex="1" style="background: green;"/>
</hbox>
<!-- same as above, but with stack-sizing: ignore; the stack should not be resized -->
<hbox style="height: 20px;">
<stack style="width: 100px; background: yellow;">
<hbox style="-moz-stack-sizing: ignore; width: 100px; height: 20px; background: transparent;" top="0" left="100"/>
</stack>
<spacer flex="1" style="background: green;"/>
</hbox>
</vbox>
</window>

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

@ -301,6 +301,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 333970-1.html 333970-1-ref.html # bug 3
== 345267-1c.html 345267-1-ref.html
== 345267-1d.html 345267-1-ref.html
!= 345563-sub.xhtml 345563-sup.xhtml
== 346189-1.xul 346189-1-ref.xul
== 346774-1a.html 346774-1-ref.html
== 346774-1b.html 346774-1-ref.html
== 346774-1c.html 346774-1-ref.html

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

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p:first-letter {
float: left;
}
</style>
<title>a first-letter testcase</title>
</head>
<body>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>

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

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p:first-letter {
float: left;
}
</style>
<title>a first-letter testcase</title>
<script type="text/javascript">
window.onload = function() {
document.getElementsByTagName("style")[0].disabled = true;
}
</script>
</head>
<body>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>a first-letter testcase</title>
</head>
<body>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>

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

@ -29,5 +29,7 @@ random == dynamic-3b.html dynamic-3-ref.html
== 23605-5.html 23605-5-ref.html
== 23605-6.html 23605-6-ref.html
random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 329069-1.html 329069-1-ref.html # failure is font-dependent, may be related to bug 404848
!= 229764-1.html 229764-ref.html
== 229764-2.html 229764-ref.html
== 342120-1.xhtml 342120-1-ref.xhtml
== 379799-1.html 379799-1-ref.html

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

@ -418,6 +418,7 @@ CSS_KEY(start, start)
CSS_KEY(static, static)
CSS_KEY(status-bar, status_bar)
CSS_KEY(stretch, stretch)
CSS_KEY(stretch-to-fit, stretch_to_fit)
CSS_KEY(sub, sub)
CSS_KEY(super, super)
CSS_KEY(sw-resize, sw_resize)

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

@ -5070,6 +5070,9 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_speech_rate:
return ParseVariant(aErrorCode, aValue, VARIANT_HN | VARIANT_KEYWORD,
nsCSSProps::kSpeechRateKTable);
case eCSSProperty_stack_sizing:
return ParseVariant(aErrorCode, aValue, VARIANT_HK,
nsCSSProps::kStackSizingKTable);
case eCSSProperty_stress:
return ParseVariant(aErrorCode, aValue, VARIANT_HN, nsnull);
case eCSSProperty_table_layout:

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

@ -516,6 +516,7 @@ CSS_PROP_XUL(-moz-box-flex, box_flex, MozBoxFlex, XUL, mBoxFlex, eCSSType_Value,
CSS_PROP_XUL(-moz-box-orient, box_orient, MozBoxOrient, XUL, mBoxOrient, eCSSType_Value, kBoxOrientKTable) // XXX bug 3935
CSS_PROP_XUL(-moz-box-pack, box_pack, MozBoxPack, XUL, mBoxPack, eCSSType_Value, kBoxPackKTable) // XXX bug 3935
CSS_PROP_XUL(-moz-box-ordinal-group, box_ordinal_group, MozBoxOrdinalGroup, XUL, mBoxOrdinal, eCSSType_Value, nsnull)
CSS_PROP_XUL(-moz-stack-sizing, stack_sizing, MozStackSizing, XUL, mStackSizing, eCSSType_Value, kStackSizingKTable)
#ifdef MOZ_MATHML
#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL

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

@ -860,6 +860,12 @@ const PRInt32 nsCSSProps::kSpeechRateKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
const PRInt32 nsCSSProps::kStackSizingKTable[] = {
eCSSKeyword_ignore, NS_STYLE_STACK_SIZING_IGNORE,
eCSSKeyword_stretch_to_fit, NS_STYLE_STACK_SIZING_STRETCH_TO_FIT,
eCSSKeyword_UNKNOWN,-1
};
const PRInt32 nsCSSProps::kTableLayoutKTable[] = {
eCSSKeyword_fixed, NS_STYLE_TABLE_LAYOUT_FIXED,
eCSSKeyword_UNKNOWN,-1

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

@ -177,6 +177,7 @@ public:
static const PRInt32 kSpeakNumeralKTable[];
static const PRInt32 kSpeakPunctuationKTable[];
static const PRInt32 kSpeechRateKTable[];
static const PRInt32 kStackSizingKTable[];
static const PRInt32 kTableLayoutKTable[];
static const PRInt32 kTextAlignKTable[];
static const PRInt32 kTextDecorationKTable[];

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

@ -548,6 +548,7 @@ struct nsCSSXUL : public nsCSSStruct {
nsCSSValue mBoxOrient;
nsCSSValue mBoxPack;
nsCSSValue mBoxOrdinal;
nsCSSValue mStackSizing;
private:
nsCSSXUL(const nsCSSXUL& aOther); // NOT IMPLEMENTED
};

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

@ -486,6 +486,18 @@ nsComputedDOMStyle::GetBottom(nsIDOMCSSValue** aValue)
return GetOffsetWidthFor(NS_SIDE_BOTTOM, aValue);
}
nsresult
nsComputedDOMStyle::GetStackSizing(nsIDOMCSSValue** aValue)
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
val->SetIdent(GetStyleXUL()->mStretchStack ? nsGkAtoms::stretch_to_fit :
nsGkAtoms::ignore);
return CallQueryInterface(val, aValue);
}
nsresult
nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue,
nscolor aColor)
@ -3806,6 +3818,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topLeft, OutlineRadiusTopLeft),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topRight, OutlineRadiusTopRight),
COMPUTED_STYLE_MAP_ENTRY(stack_sizing, StackSizing),
COMPUTED_STYLE_MAP_ENTRY(user_focus, UserFocus),
COMPUTED_STYLE_MAP_ENTRY(user_input, UserInput),
COMPUTED_STYLE_MAP_ENTRY(user_modify, UserModify),

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

@ -133,6 +133,7 @@ private:
nsresult GetTop(nsIDOMCSSValue** aValue);
nsresult GetRight(nsIDOMCSSValue** aValue);
nsresult GetBottom(nsIDOMCSSValue** aValue);
nsresult GetStackSizing(nsIDOMCSSValue** aValue);
/* Font properties */
nsresult GetColor(nsIDOMCSSValue** aValue);

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

@ -4525,6 +4525,16 @@ nsRuleNode::ComputeXULData(void* aStartStruct,
xul->mBoxOrdinal = 1;
}
if (eCSSUnit_Inherit == xulData.mStackSizing.GetUnit()) {
inherited = PR_TRUE;
xul->mStretchStack = parentXUL->mStretchStack;
} else if (eCSSUnit_Initial == xulData.mStackSizing.GetUnit()) {
xul->mStretchStack = PR_TRUE;
} else if (eCSSUnit_Enumerated == xulData.mStackSizing.GetUnit()) {
xul->mStretchStack = xulData.mStackSizing.GetIntValue() ==
NS_STYLE_STACK_SIZING_STRETCH_TO_FIT;
}
COMPUTE_END_RESET(XUL, xul)
}

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

@ -573,6 +573,7 @@ nsStyleXUL::nsStyleXUL()
mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
mBoxPack = NS_STYLE_BOX_PACK_START;
mBoxOrdinal = 1;
mStretchStack = PR_TRUE;
}
nsStyleXUL::~nsStyleXUL()

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

@ -1187,6 +1187,7 @@ struct nsStyleXUL {
PRUint8 mBoxDirection; // [reset] see nsStyleConsts.h
PRUint8 mBoxOrient; // [reset] see nsStyleConsts.h
PRUint8 mBoxPack; // [reset] see nsStyleConsts.h
PRPackedBool mStretchStack; // [reset] see nsStyleConsts.h
};
struct nsStyleColumn {

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

@ -442,6 +442,14 @@ var gCSSProperties = {
other_values: [ "1px", "3em" ],
invalid_values: []
},
"-moz-stack-sizing": {
domProp: "MozStackSizing",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "stretch-to-fit" ],
other_values: [ "ignore" ],
invalid_values: []
},
"-moz-user-focus": {
domProp: "MozUserFocus",
inherited: true,

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

@ -76,29 +76,35 @@ nsStackLayout::nsStackLayout()
{
}
/*
* Sizing: we are as wide as the widest child plus its left offset
* we are tall as the tallest child plus its top offset.
*
* Only children which have -moz-stack-sizing set to stretch-to-fit
* (the default) will be included in the size computations.
*/
nsSize
nsStackLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState)
{
nsSize rpref (0, 0);
// we are as wide as the widest child plus its left offset
// we are tall as the tallest child plus its top offset
nsSize prefSize (0, 0);
nsIBox* child = aBox->GetChildBox();
while (child) {
nsSize pref = child->GetPrefSize(aState);
while (child) {
if (child->GetStyleXUL()->mStretchStack) {
nsSize pref = child->GetPrefSize(aState);
AddMargin(child, pref);
AddOffset(aState, child, pref);
AddLargestSize(rpref, pref);
AddMargin(child, pref);
AddOffset(aState, child, pref);
AddLargestSize(prefSize, pref);
}
child = child->GetNextBox();
}
// now add our border and padding
AddBorderAndPadding(aBox, rpref);
AddBorderAndPadding(aBox, prefSize);
return rpref;
return prefSize;
}
nsSize
@ -106,19 +112,19 @@ nsStackLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState)
{
nsSize minSize (0, 0);
// run through all the children and get their min, max, and preferred sizes
nsIBox* child = aBox->GetChildBox();
while (child) {
nsSize min = child->GetMinSize(aState);
AddMargin(child, min);
AddOffset(aState, child, min);
AddLargestSize(minSize, min);
while (child) {
if (child->GetStyleXUL()->mStretchStack) {
nsSize min = child->GetMinSize(aState);
AddMargin(child, min);
AddOffset(aState, child, min);
AddLargestSize(minSize, min);
}
child = child->GetNextBox();
}
// now add our border and padding
AddBorderAndPadding(aBox, minSize);
return minSize;
@ -129,21 +135,22 @@ nsStackLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aState)
{
nsSize maxSize (NS_INTRINSICSIZE, NS_INTRINSICSIZE);
// run through all the children and get their min, max, and preferred sizes
nsIBox* child = aBox->GetChildBox();
while (child) {
nsSize min = child->GetMinSize(aState);
nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
while (child) {
if (child->GetStyleXUL()->mStretchStack) {
nsSize min = child->GetMinSize(aState);
nsSize max = child->GetMaxSize(aState);
AddMargin(child, max);
AddOffset(aState, child, max);
AddSmallestSize(maxSize, max);
max = nsBox::BoundsCheckMinMax(min, max);
AddMargin(child, max);
AddOffset(aState, child, max);
AddSmallestSize(maxSize, max);
}
child = child->GetNextBox();
}
// now add our border and padding
AddBorderAndPadding(aBox, maxSize);
return maxSize;
@ -292,15 +299,17 @@ nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
childRectNoMargin = childRect = child->GetRect();
childRect.Inflate(margin);
// Did the child push back on us and get bigger?
if (offset.width + childRect.width > clientRect.width) {
clientRect.width = childRect.width + offset.width;
grow = PR_TRUE;
}
if (child->GetStyleXUL()->mStretchStack) {
// Did the child push back on us and get bigger?
if (offset.width + childRect.width > clientRect.width) {
clientRect.width = childRect.width + offset.width;
grow = PR_TRUE;
}
if (offset.height + childRect.height > clientRect.height) {
clientRect.height = childRect.height + offset.height;
grow = PR_TRUE;
if (offset.height + childRect.height > clientRect.height) {
clientRect.height = childRect.height + offset.height;
grow = PR_TRUE;
}
}
if (childRectNoMargin != oldRect)

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

@ -1,3 +1,42 @@
// ***** 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 the Public Suffix List.
//
// The Initial Developer of the Original Code is
// Jo Hermans <jo.hermans@gmail.com>.
// Portions created by the Initial Developer are Copyright (C) 2007
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Ruben Arakelyan <ruben@wackomenace.co.uk>
//
// 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 *****
// $Id$
// ac : http://en.wikipedia.org/wiki/.ac
ac
com.ac

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

@ -10,6 +10,8 @@ include('unstable/adts.js');
include('unstable/analysis.js');
include('unstable/esp.js');
include('unstable/liveness.js');
let Zero_NonZero = {};
include('unstable/zero_nonzero.js', Zero_NonZero);
include('mayreturn.js');
@ -148,7 +150,8 @@ function OutparamCheck(cfg, psem_list, outparam_list, retvar, retvar_set, finall
print(" " + expr_display(v));
}
}
ESP.Analysis.call(this, cfg, this.psvar_list, av.BOTTOM, av.meet, trace);
this.zeroNonzero = new Zero_NonZero.Zero_NonZero();
ESP.Analysis.call(this, cfg, this.psvar_list, av.meet, trace);
}
// Abstract values for outparam check
@ -165,10 +168,11 @@ AbstractValue.prototype.toString = function() {
return this.name + ' (' + this.ch + ')';
}
let avspec = [
// General-purpose abstract values
[ 'BOTTOM', '.' ], // any value, also used for dead vars
AbstractValue.prototype.toShortString = function() {
return this.ch;
}
let avspec = [
// Abstract values for outparam contents write status
[ 'NULL', 'x' ], // is a null pointer
[ 'NOT_WRITTEN', '-' ], // not written
@ -180,10 +184,6 @@ let avspec = [
// in last position), so if there is an error with it not being written,
// we can give a hint about the possible outparam in the warning.
[ 'MAYBE_WRITTEN', '?' ], // written if possible outparam is one
// Abstract values for rvs
[ 'ZERO', '0' ], // zero value
[ 'NONZERO', '1' ] // nonzero value
];
let av = {};
@ -191,11 +191,13 @@ for each (let [name, ch] in avspec) {
av[name] = new AbstractValue(name, ch);
}
av.ZERO = Zero_NonZero.Lattice.ZERO;
av.NONZERO = Zero_NonZero.Lattice.NONZERO;
/*
av.ZERO.negation = av.NONZERO;
av.NONZERO.negation = av.ZERO;
let cachedAVs = {};
// Abstract values for int constants. We use these to figure out feasible
// paths in the presence of GCC finally_tmp-controlled switches.
function makeIntAV(v) {
@ -207,13 +209,16 @@ function makeIntAV(v) {
ans.int_val = v;
return ans;
}
*/
let cachedAVs = {};
// Abstract values for pointers that contain a copy of an outparam
// pointer. We use these to figure out writes to a casted copy of
// an outparam passed to another method.
function makeOutparamAV(v) {
let key = 'outparam_' + DECL_UID(v);
if (cachedAVs.hasOwnProperty(key)) return cachedAVs[key];
if (key in cachedAVs) return cachedAVs[key];
let ans = cachedAVs[key] =
new AbstractValue('OUTPARAM:' + expr_display(v), 'P');
@ -230,31 +235,14 @@ av.intVal = function(v) {
/** Meet function for our abstract values. */
av.meet = function(v1, v2) {
// Important for following cases -- as output, undefined means top here.
if (v1 == undefined) v1 = av.BOTTOM;
if (v2 == undefined) v2 = av.BOTTOM;
// These cases apply for any lattice.
if (v1 == av.BOTTOM) return v2;
if (v2 == av.BOTTOM) return v1;
if (v1 == v2) return v1;
// At this point we know v1 != v2.
switch (v1) {
case av.ZERO:
return av.intVal(v2) == 0 ? v2 : undefined;
case av.NONZERO:
// Return a nonempty meet only if the other value is an integer
// and is nonzero.
let iv2 = av.intVal(v2);
return iv2 != undefined && iv2 != 0 ? v2 : undefined;
default:
let iv = av.intVal(v1);
if (iv == 0) return v2 == av.ZERO ? v1 : undefined;
if (iv != undefined) return v2 == av.NONZERO ? v1 : undefined;
return undefined;
}
}
let values = [v1,v2]
if (values.indexOf(av.LOCKED) != -1
|| values.indexOf(av.UNLOCKED) != -1)
return ESP.NOT_REACHED;
return Zero_NonZero.meet(v1, v2)
};
// Outparam check analysis
OutparamCheck.prototype = new ESP.Analysis;
@ -262,11 +250,17 @@ OutparamCheck.prototype = new ESP.Analysis;
OutparamCheck.prototype.startValues = function() {
let ans = create_decl_map();
for each (let p in this.psvar_list) {
ans.put(p, this.outparams.has(p) ? av.NOT_WRITTEN : av.BOTTOM);
ans.put(p, this.outparams.has(p) ? av.NOT_WRITTEN : ESP.TOP);
}
return ans;
}
OutparamCheck.prototype.split = function(vbl, v) {
// Can't happen for current version of ESP, but could change
if (v != ESP.TOP) throw new Error("not implemented");
return [ av.ZERO, av.NONZERO ];
}
OutparamCheck.prototype.updateEdgeState = function(e) {
e.state.keepOnly(e.dest.keepVars);
}
@ -283,93 +277,17 @@ OutparamCheck.prototype.flowState = function(isn, state) {
case COND_EXPR:
// This gets handled by flowStateCond instead, has no exec effect
break;
case RETURN_EXPR:
let op = isn.operands()[0];
if (op) this.processAssign(isn.operands()[0], state);
break;
case LABEL_EXPR:
case RESX_EXPR:
case ASM_EXPR:
// NOPs for us
break;
default:
print(TREE_CODE(isn));
throw new Error("ni");
this.zeroNonzero.flowState(isn, state);
}
}
OutparamCheck.prototype.flowStateCond = function(isn, truth, state) {
switch (TREE_CODE(isn)) {
case COND_EXPR:
this.flowStateIf(isn, truth, state);
break;
case SWITCH_EXPR:
this.flowStateSwitch(isn, truth, state);
break;
default:
throw new Error("ni " + TREE_CODE(isn));
}
this.zeroNonzero.flowStateCond(isn, truth, state);
}
OutparamCheck.prototype.flowStateIf = function(isn, truth, state) {
let exp = TREE_OPERAND(isn, 0);
if (DECL_P(exp)) {
this.filter(state, exp, av.NONZERO, truth, isn);
return;
}
switch (TREE_CODE(exp)) {
case EQ_EXPR:
case NE_EXPR:
// Handle 'x op <int lit>' pattern only
let op1 = TREE_OPERAND(exp, 0);
let op2 = TREE_OPERAND(exp, 1);
if (expr_literal_int(op1) != undefined) {
[op1,op2] = [op2,op1];
}
if (!DECL_P(op1)) break;
if (expr_literal_int(op2) != 0) break;
let val = TREE_CODE(exp) == EQ_EXPR ? av.ZERO : av.NONZERO;
this.filter(state, op1, val, truth, isn);
break;
default:
// Don't care about anything else.
}
};
OutparamCheck.prototype.flowStateSwitch = function(isn, truth, state) {
let exp = TREE_OPERAND(isn, 0);
if (DECL_P(exp)) {
if (truth != null) {
this.filter(state, exp, makeIntAV(truth), true, isn);
}
return;
}
throw new Error("ni");
}
// Apply a filter to the state. We need to special case it for this analysis
// because outparams only care about being a NULL pointer.
OutparamCheck.prototype.filter = function(state, vbl, val, truth, blame) {
if (truth != true && truth != false) throw new Error("ni " + truth);
if (this.outparams.has(vbl)) {
// We do need to check for true and false here because other values
// could get passed in from switches.
if (truth == true && val == av.ZERO || truth == false && val == av.NONZERO) {
state.assignValue(vbl, av.NULL, blame);
}
} else {
if (truth == false) {
val = val.negation;
}
state.filter(vbl, val, blame);
}
};
// For any outparams-specific semantics, we handle it here and then
// return. Otherwise we delegate to the zero-nonzero analysis.
OutparamCheck.prototype.processAssign = function(isn, state) {
let lhs = isn.operands()[0];
let rhs = isn.operands()[1];
@ -380,40 +298,20 @@ OutparamCheck.prototype.processAssign = function(isn, state) {
rhs = rhs.operands()[0];
}
if (DECL_P(rhs)) {
if (this.outparams.has(rhs)) {
if (DECL_P(rhs) && this.outparams.has(rhs)) {
// Copying an outparam pointer. We have to remember this so that
// if it is assigned thru later, we pick up the write.
state.assignValue(lhs, makeOutparamAV(rhs), isn);
} else {
state.assign(lhs, rhs, isn);
}
return
return;
}
switch (TREE_CODE(rhs)) {
case INTEGER_CST:
if (this.outparams.has(lhs)) {
warning("assigning to outparam pointer");
} else {
// Need to know the exact int value for finally_tmp.
if (is_finally_tmp(lhs)) {
let v = TREE_INT_CST_LOW(rhs);
state.assignValue(lhs, makeIntAV(v), isn);
} else {
let value = expr_literal_int(rhs) == 0 ? av.ZERO : av.NONZERO;
state.assignValue(lhs, value, isn);
}
return;
}
break;
case NE_EXPR: {
// We only care about gcc-generated x != 0 for conversions and such.
let [op1, op2] = rhs.operands();
if (DECL_P(op1) && expr_literal_int(op2) == 0) {
state.assign(lhs, op1, isn);
}
}
break;
case EQ_EXPR: {
// We only care about testing outparams for NULL (and then not writing)
let [op1, op2] = rhs.operands();
@ -425,6 +323,7 @@ OutparamCheck.prototype.processAssign = function(isn, state) {
s2.assignValue(lhs, av.ZERO, isn);
return [s1, s2];
});
return;
}
}
break;
@ -440,40 +339,18 @@ OutparamCheck.prototype.processAssign = function(isn, state) {
} else {
this.processCall(lhs, rhs, isn, state);
}
break;
// Stuff we don't analyze -- just kill the LHS info
case ADDR_EXPR:
case POINTER_PLUS_EXPR:
case ARRAY_REF:
case COMPONENT_REF:
case INDIRECT_REF:
case FILTER_EXPR:
case EXC_PTR_EXPR:
case CONSTRUCTOR:
case REAL_CST:
case STRING_CST:
case CONVERT_EXPR:
case TRUTH_NOT_EXPR:
case TRUTH_XOR_EXPR:
case BIT_FIELD_REF:
state.remove(lhs);
break;
default:
if (UNARY_CLASS_P(rhs) || BINARY_CLASS_P(rhs) || COMPARISON_CLASS_P(rhs)) {
state.remove(lhs);
break;
}
print(TREE_CODE(rhs));
throw new Error("ni");
return;
}
// Nothing special -- delegate
this.zeroNonzero.processAssign(isn, state);
return;
}
switch (TREE_CODE(lhs)) {
case INDIRECT_REF:
// Writing to an outparam. We want to try to figure out if we're writing NULL.
// Writing to an outparam. We want to try to figure out if we're
// writing NULL.
let e = TREE_OPERAND(lhs, 0);
if (this.outparams.has(e)) {
if (expr_literal_int(rhs) == 0) {
@ -509,9 +386,9 @@ OutparamCheck.prototype.processAssign = function(isn, state) {
OutparamCheck.prototype.processTest = function(lhs, call, val, blame, state) {
let arg = call_arg(call, 0);
if (DECL_P(arg)) {
state.predicate(lhs, val, arg, blame);
this.zeroNonzero.predicate(state, lhs, val, arg, blame);
} else {
state.assignValue(lhs, av.BOTTOM, blame);
state.assignValue(lhs, ESP.TOP, blame);
}
};
@ -650,14 +527,13 @@ OutparamCheck.prototype.checkSubstate = function(isvoid, fndecl, ss) {
} else {
let [succ, fail] = ret_coding(fndecl);
let rv = ss.get(this.retvar);
switch (rv) {
case succ:
// We want to check if the abstract value of the rv is entirely
// contained in the success or failure condition.
if (av.meet(rv, succ) == rv) {
this.checkSubstateSuccess(ss);
break;
case fail:
} else if (av.meet(rv, fail) == rv) {
this.checkSubstateFailure(ss);
break;
default:
} else {
// This condition indicates a bug in outparams.js. We'll just
// warn so we don't break static analysis builds.
warning("Outparams checker cannot determine rv success/failure",

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

@ -74,7 +74,7 @@
#define NS_ABORT_IF_FALSE(_expr, _msg) \
PR_BEGIN_MACRO \
if (!(_expr)) { \
NS_DebugBreak(NS_DEBUG_ASSERTION, _msg, #_expr, __FILE__, __LINE__); \
NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_expr, __FILE__, __LINE__); \
} \
PR_END_MACRO