Merge.
Merge.
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -80,17 +80,18 @@
PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
//-----------------------------------------------------
// construction
//-----------------------------------------------------
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)
return;
// Because of the way document loading happens, the new nsIWidget is created before
// the old one is removed. Since it creates the nsDocAccessible, for a brief moment
// there can be 2 nsDocAccessible's for the content area, although for 2 different
@@ -584,17 +585,20 @@ NS_IMETHODIMP nsDocAccessible::Shutdown(
if (mFireEventTimer) {
// Doc being shut down before events fired,
mFireEventTimer->Cancel();
mFireEventTimer = nsnull;
if (mEventsToFire.Count() > 0 ) {
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();
}
}
// Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it.
// We don't do this during ShutdownAccessibility() because that is already clearing the cache
if (!gIsShuttingDownApp)
gGlobalDocAccessibleCache.Remove(static_cast<void*>(kungFuDeathGripDoc));
@@ -1500,16 +1504,17 @@ nsDocAccessible::FireDelayedAccessibleEv
0, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
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();
if (!presShell)
length = 0; // The doc is now shut down, don't fire events in it anymore
else
nsAccEvent::ApplyEventRules(mEventsToFire);
@@ -1620,17 +1625,18 @@ NS_IMETHODIMP nsDocAccessible::FlushPend
// Test caret line # -- fire an EVENT_ALERT on the focused node so we can watch the
// line-number object attribute on it
nsCOMPtr<nsIAccessible> accForFocus;
GetAccService()->GetAccessibleFor(gLastFocusedNode, getter_AddRefs(accForFocus));
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
#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);
PRInt32 selectionCount;
accessibleText->GetSelectionCount(&selectionCount);
if (selectionCount) { // There's a selection so fire selection change as well
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
accessible, PR_TRUE);
@@ -1656,16 +1662,17 @@ NS_IMETHODIMP nsDocAccessible::FlushPend
}
}
mEventsToFire.Clear(); // Clear out array
NS_RELEASE_THIS(); // Release kung fu death grip
// After a flood of events, reset so that user input flag is off
nsAccEvent::ResetLastInputState();
+ mInFlushPendingEvents = PR_FALSE;
return NS_OK;
}
void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
{
nsPIAccessibleDocument *accessibleDoc = static_cast<nsPIAccessibleDocument*>(aClosure);
NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
if (accessibleDoc) {
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -216,13 +216,14 @@ class nsDocAccessible : public nsHyperTe
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
PRPackedBool mIsContentLoaded;
PRPackedBool mIsLoadCompleteFired;
nsCOMArray<nsIAccessibleEvent> mEventsToFire;
protected:
PRBool mIsAnchor;
PRBool mIsAnchorJumped;
+ PRBool mInFlushPendingEvents;
static PRUint32 gLastFocusedAccessiblesState;
static nsIAtom *gLastFocusedFrameType;
};
#endif
--- a/configure.in
+++ b/configure.in
@@ -4251,16 +4251,28 @@ MOZ_ARG_WITH_STRING(java-include-path,
JAVA_INCLUDE_PATH=$withval)
JAVA_BIN_PATH=
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
dnl =
dnl ========================================================
MOZ_ARG_HEADER(Application)
BUILD_STATIC_LIBS=
@@ -8259,16 +8271,19 @@ if test -z "$MOZ_NATIVE_NSPR" || test "$
ac_configure_args="$ac_configure_args --enable-optimize"
fi
if test "$OS_ARCH" = "WINNT" && test "$NS_TRACE_MALLOC"; then
ac_configure_args="$ac_configure_args --enable-debug --disable-optimize"
fi
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
if test -z "$MOZ_NATIVE_NSPR"; then
# Hack to deal with the fact that we use NSPR_CFLAGS everywhere
AC_MSG_WARN([Recreating autoconf.mk with updated nspr-config output])
if test ! "$VACPP" && test "$OS_ARCH" != "WINNT" && test "$OS_ARCH" != "WINCE"; then
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -392,16 +392,17 @@ GK_ATOM(hspace, "hspace")
GK_ATOM(html, "html")
GK_ATOM(htmlBaseHref, "html-base-href")
GK_ATOM(htmlBaseTarget, "html-base-target")
GK_ATOM(httpEquiv, "http-equiv")
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")
GK_ATOM(image, "image")
GK_ATOM(imageClickedPoint, "image-clicked-point")
GK_ATOM(img, "img")
GK_ATOM(implementation, "implementation")
GK_ATOM(implements, "implements")
@@ -797,16 +798,17 @@ GK_ATOM(start_after, "start_after")
GK_ATOM(start_before, "start_before")
GK_ATOM(startsWith, "starts-with")
GK_ATOM(state, "state")
GK_ATOM(statedatasource, "statedatasource")
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")
GK_ATOM(stripSpace, "strip-space")
GK_ATOM(strong, "strong")
GK_ATOM(style, "style")
GK_ATOM(stylesheet, "stylesheet")
GK_ATOM(stylesheetPrefix, "stylesheet-prefix")
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -3872,29 +3872,31 @@ nsHTMLDocument::GetDocumentAllResult(con
}
if (!entry->mDocAllList) {
entry->mDocAllList = new nsContentList(root, DocAllResultMatch,
nsnull, nsnull, PR_TRUE, id);
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;
}
static void
NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument,
PRBool aEditable)
{
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -147,16 +147,18 @@
#include "nsReadableUtils.h"
#include "nsITimelineService.h"
#include "nsIFrame.h"
#include "nsNodeInfoManager.h"
#include "nsXBLBinding.h"
#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.
*/
#define XUL_ELEMENT_CHILDREN_MUST_BE_REBUILT \
(nsXULElement::eChildrenMustBeRebuilt << XUL_ELEMENT_LAZY_STATE_OFFSET)
#define XUL_ELEMENT_TEMPLATE_CONTENTS_BUILT \
@@ -1643,16 +1645,32 @@ nsXULElement::PreHandleEvent(nsEventChai
if (!aVisitor.mDOMEvent) {
// We need to create a new DOMEvent for the original event
nsEventDispatcher::CreateEvent(aVisitor.mPresContext,
aVisitor.mEvent,
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;
nsEventDispatcher::Dispatch(commandContent,
aVisitor.mPresContext,
&event, nsnull, &status);
} else {
NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
--- a/dom/public/idl/css/nsIDOMCSS2Properties.idl
+++ b/dom/public/idl/css/nsIDOMCSS2Properties.idl
@@ -401,17 +401,17 @@ interface nsIDOMCSS2Properties : nsISupp
attribute DOMString wordSpacing;
// raises(DOMException) on setting
attribute DOMString zIndex;
// 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 */
/* Mozilla extension CSS properties */
attribute DOMString MozAppearance;
// raises(DOMException) on setting
@@ -586,9 +586,11 @@ interface nsIDOMNSCSS2Properties : nsIDO
// raises(DOMException) on setting
attribute DOMString MozBorderStartStyle;
// raises(DOMException) on setting
attribute DOMString MozBorderStartWidth;
// raises(DOMException) on setting
+ attribute DOMString MozStackSizing;
+ // raises(DOMException) on setting
};
new file mode 100644
--- /dev/null
+++ b/intl/uconv/tests/unit/test_bug396637.js
@@ -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);
+}
new file mode 100644
--- /dev/null
+++ b/intl/uconv/tests/unit/test_bug399257.js
@@ -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");
+ }
+}
--- a/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp
+++ b/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp
@@ -54,21 +54,23 @@ UTF16ConvertToUnicode(PRUint8& aState, P
{
const char* src = aSrc;
const char* srcEnd = aSrc + *aSrcLength;
PRUnichar* dest = aDest;
PRUnichar* destEnd = aDest + *aDestLength;
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
// deal with the same endian case. That is, 0xFFFE (byte-swapped BOM) is
// illegal.
if(0xFEFF == *((PRUnichar*)src)) {
src+=2;
} else if(0xFFFE == *((PRUnichar*)src)) {
@@ -154,17 +156,18 @@ nsUTF16BEToUnicode::Convert(const char *
PRUnichar * aDest, PRInt32 * aDestLength)
{
#ifdef IS_LITTLE_ENDIAN
// Remove the BOM if we're little-endian. The 'same endian' case with the
// leading BOM will be taken care of by |UTF16ConvertToUnicode|.
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;
} else if(0xFEFF == *((PRUnichar*)aSrc)) {
*aSrcLength=0;
*aDestLength=0;
return NS_ERROR_ILLEGAL_INPUT;
}
@@ -185,17 +188,18 @@ nsUTF16LEToUnicode::Convert(const char *
PRUnichar * aDest, PRInt32 * aDestLength)
{
#ifdef IS_BIG_ENDIAN
// Remove the BOM if we're big-endian. The 'same endian' case with the
// leading BOM will be taken care of by |UTF16ConvertToUnicode|.
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;
} else if(0xFEFF == *((PRUnichar*)aSrc)) {
*aSrcLength=0;
*aDestLength=0;
return NS_ERROR_ILLEGAL_INPUT;
}
@@ -221,17 +225,18 @@ nsUTF16ToUnicode::Reset()
NS_IMETHODIMP
nsUTF16ToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength)
{
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.
if(0xFF == PRUint8(aSrc[0]) && 0xFE == PRUint8(aSrc[1])) {
mState = STATE_FOUND_BOM;
mEndian = kLittleEndian;
mFoundBOM = PR_TRUE;
}
--- a/intl/uconv/util/nsUnicodeEncodeHelper.cpp
+++ b/intl/uconv/util/nsUnicodeEncodeHelper.cpp
@@ -57,18 +57,23 @@ nsresult nsUnicodeEncodeHelper::ConvertB
PRInt32 destLen = *aDestLength;
PRUnichar med;
PRInt32 bcw; // byte count for write;
nsresult res = NS_OK;
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;
if (aScanClass == uMultibytesCharset) {
NS_ASSERTION(aShiftOutTable, "shift table missing");
charFound = uGenerateShift(aShiftOutTable, 0, med,
(PRUint8 *)dest, destLen,
(PRUint32 *)&bcw);
--- a/js/src/jslock.cpp
+++ b/js/src/jslock.cpp
@@ -173,16 +173,34 @@ 1:"
#include <sys/atomic_op.h>
static JS_INLINE int
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."
#endif /* arch-tests */
#endif /* !NSPR_LOCK */
--- a/js/src/jslock.h
+++ b/js/src/jslock.h
@@ -221,17 +221,17 @@ extern void js_SetScopeInfo(JSScope *sco
JSRuntime *_rt = (cx)->runtime; \
JS_LOCK_RUNTIME_VOID(_rt, e); \
JS_END_MACRO
#if defined(JS_USE_ONLY_NSPR_LOCKS) || \
!( (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
#undef JS_LOCK0
#undef JS_UNLOCK0
#define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M))
#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat)))
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -123,16 +123,20 @@
// box-direction
#define NS_STYLE_BOX_DIRECTION_NORMAL 0
#define NS_STYLE_BOX_DIRECTION_REVERSE 1
// box-orient
#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
#define NS_STYLE_AZIMUTH_LEFT 0x02
#define NS_STYLE_AZIMUTH_CENTER_LEFT 0x03
#define NS_STYLE_AZIMUTH_CENTER 0x04
#define NS_STYLE_AZIMUTH_CENTER_RIGHT 0x05
#define NS_STYLE_AZIMUTH_RIGHT 0x06
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/346189-1-ref.xul
@@ -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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/346189-1.xul
@@ -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>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -296,16 +296,17 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") ==
== 341043-1a.html 341043-1-ref.html
!= 341043-1b.html 341043-1-ref.html
== 343540-1.html 343540-1-ref.html
== 345267-1a.html 345267-1-ref.html
== 345267-1b.html 345267-1-ref.html
== 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
== 347348-1.xhtml 347348-1-ref.xhtml
skip-if(MOZ_WIDGET_TOOLKIT=="windows") == 347496-1.xhtml 347496-1-ref.xhtml # Bug 409150
== 347912-1.html 347912-1-ref.html
== 348049-1.xhtml 348049-1-ref.xhtml
== 348516-1.html 348516-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/first-letter/229764-1.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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/first-letter/229764-2.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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/first-letter/229764-ref.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>
--- a/layout/reftests/first-letter/reftest.list
+++ b/layout/reftests/first-letter/reftest.list
@@ -24,10 +24,12 @@ fails == dynamic-1.html dynamic-1-ref.ht
random == dynamic-3b.html dynamic-3-ref.html
== 23605-1.html 23605-1-ref.html
== 23605-2.html 23605-2-ref.html
== 23605-3.html 23605-3-ref.html
== 23605-4.html 23605-4-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
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -413,16 +413,17 @@ CSS_KEY(smaller, smaller)
CSS_KEY(soft, soft)
CSS_KEY(solid, solid)
CSS_KEY(spell-out, spell_out)
CSS_KEY(square, square)
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)
CSS_KEY(table, table)
CSS_KEY(table-caption, table_caption)
CSS_KEY(table-cell, table_cell)
CSS_KEY(table-column, table_column)
CSS_KEY(table-column-group, table_column_group)
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5065,16 +5065,19 @@ PRBool CSSParserImpl::ParseSingleValuePr
return ParseVariant(aErrorCode, aValue, VARIANT_HK,
nsCSSProps::kSpeakNumeralKTable);
case eCSSProperty_speak_punctuation:
return ParseVariant(aErrorCode, aValue, VARIANT_HOK,
nsCSSProps::kSpeakPunctuationKTable);
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:
return ParseVariant(aErrorCode, aValue, VARIANT_AHK,
nsCSSProps::kTableLayoutKTable);
case eCSSProperty_text_align:
// When we support aligning on a string, we can parse text-align
// as a string....
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -511,16 +511,17 @@ CSS_PROP_TEXT(word-spacing, word_spacing
CSS_PROP_POSITION(z-index, z_index, ZIndex, Position, mZIndex, eCSSType_Value, nsnull)
CSS_PROP_XUL(-moz-box-align, box_align, MozBoxAlign, XUL, mBoxAlign, eCSSType_Value, kBoxAlignKTable) // XXX bug 3935
CSS_PROP_XUL(-moz-box-direction, box_direction, MozBoxDirection, XUL, mBoxDirection, eCSSType_Value, kBoxDirectionKTable) // XXX bug 3935
CSS_PROP_XUL(-moz-box-flex, box_flex, MozBoxFlex, XUL, mBoxFlex, eCSSType_Value, nsnull) // XXX bug 3935
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
CSS_PROP_FONT(-moz-script-level, script_level, ScriptLevel, Font, mScriptLevel, eCSSType_Value, nsnull)
CSS_PROP_FONT(-moz-script-size-multiplier, script_size_multiplier, ScriptSizeMultiplier, Font, mScriptSizeMultiplier, eCSSType_Value, nsnull)
CSS_PROP_FONT(-moz-script-min-size, script_min_size, ScriptMinSize, Font, mScriptMinSize, eCSSType_Value, nsnull)
#endif
#endif
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -855,16 +855,22 @@ const PRInt32 nsCSSProps::kSpeechRateKTa
eCSSKeyword_medium, NS_STYLE_SPEECH_RATE_MEDIUM,
eCSSKeyword_fast, NS_STYLE_SPEECH_RATE_FAST,
eCSSKeyword_x_fast, NS_STYLE_SPEECH_RATE_X_FAST,
eCSSKeyword_faster, NS_STYLE_SPEECH_RATE_FASTER,
eCSSKeyword_slower, NS_STYLE_SPEECH_RATE_SLOWER,
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
};
const PRInt32 nsCSSProps::kTextAlignKTable[] = {
eCSSKeyword_left, NS_STYLE_TEXT_ALIGN_LEFT,
eCSSKeyword_right, NS_STYLE_TEXT_ALIGN_RIGHT,
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -172,16 +172,17 @@ public:
static const PRInt32 kPageSizeKTable[];
static const PRInt32 kPitchKTable[];
static const PRInt32 kPositionKTable[];
static const PRInt32 kSpeakKTable[];
static const PRInt32 kSpeakHeaderKTable[];
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[];
static const PRInt32 kTextTransformKTable[];
static const PRInt32 kUnicodeBidiKTable[];
static const PRInt32 kUserFocusKTable[];
static const PRInt32 kUserInputKTable[];
static const PRInt32 kUserModifyKTable[];
--- a/layout/style/nsCSSStruct.h
+++ b/layout/style/nsCSSStruct.h
@@ -543,16 +543,17 @@ struct nsCSSXUL : public nsCSSStruct {
~nsCSSXUL(void);
nsCSSValue mBoxAlign;
nsCSSValue mBoxDirection;
nsCSSValue mBoxFlex;
nsCSSValue mBoxOrient;
nsCSSValue mBoxPack;
nsCSSValue mBoxOrdinal;
+ nsCSSValue mStackSizing;
private:
nsCSSXUL(const nsCSSXUL& aOther); // NOT IMPLEMENTED
};
struct nsRuleDataXUL : public nsCSSXUL {
nsRuleDataXUL() {}
private:
nsRuleDataXUL(const nsRuleDataXUL& aOther); // NOT IMPLEMENTED
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -482,16 +482,28 @@ nsComputedDOMStyle::GetCssFloat(nsIDOMCS
nsresult
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)
{
if (NS_GET_A(aColor) == 0) {
aValue->SetIdent(nsGkAtoms::transparent);
return NS_OK;
}
@@ -3801,16 +3813,17 @@ nsComputedDOMStyle::GetQueryableProperty
COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap, ColumnGap),
COMPUTED_STYLE_MAP_ENTRY(float_edge, FloatEdge),
COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon, ForceBrokenImageIcon),
COMPUTED_STYLE_MAP_ENTRY(image_region, ImageRegion),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft),
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),
COMPUTED_STYLE_MAP_ENTRY(user_select, UserSelect)
#ifdef MOZ_SVG
,
COMPUTED_STYLE_MAP_ENTRY(clip_path, ClipPath),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -128,16 +128,17 @@ private:
nsresult GetMaxHeight(nsIDOMCSSValue** aValue);
nsresult GetMaxWidth(nsIDOMCSSValue** aValue);
nsresult GetMinHeight(nsIDOMCSSValue** aValue);
nsresult GetMinWidth(nsIDOMCSSValue** aValue);
nsresult GetLeft(nsIDOMCSSValue** aValue);
nsresult GetTop(nsIDOMCSSValue** aValue);
nsresult GetRight(nsIDOMCSSValue** aValue);
nsresult GetBottom(nsIDOMCSSValue** aValue);
+ nsresult GetStackSizing(nsIDOMCSSValue** aValue);
/* Font properties */
nsresult GetColor(nsIDOMCSSValue** aValue);
nsresult GetFontFamily(nsIDOMCSSValue** aValue);
nsresult GetFontStyle(nsIDOMCSSValue** aValue);
nsresult GetFontSize(nsIDOMCSSValue** aValue);
nsresult GetFontSizeAdjust(nsIDOMCSSValue** aValue);
nsresult GetFontWeight(nsIDOMCSSValue** aValue);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -4520,16 +4520,26 @@ nsRuleNode::ComputeXULData(void* aStartS
xul->mBoxOrdinal = xulData.mBoxOrdinal.GetIntValue();
} else if (eCSSUnit_Inherit == xulData.mBoxOrdinal.GetUnit()) {
inherited = PR_TRUE;
xul->mBoxOrdinal = parentXUL->mBoxOrdinal;
} else if (eCSSUnit_Initial == xulData.mBoxOrdinal.GetUnit()) {
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)
}
const void*
nsRuleNode::ComputeColumnData(void* aStartStruct,
const nsRuleDataStruct& aData,
nsStyleContext* aContext,
nsRuleNode* aHighestNode,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -568,16 +568,17 @@ nsChangeHint nsStyleList::MaxDifference(
nsStyleXUL::nsStyleXUL()
{
mBoxAlign = NS_STYLE_BOX_ALIGN_STRETCH;
mBoxDirection = NS_STYLE_BOX_DIRECTION_NORMAL;
mBoxFlex = 0.0f;
mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
mBoxPack = NS_STYLE_BOX_PACK_START;
mBoxOrdinal = 1;
+ mStretchStack = PR_TRUE;
}
nsStyleXUL::~nsStyleXUL()
{
}
nsStyleXUL::nsStyleXUL(const nsStyleXUL& aSource)
{
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1182,16 +1182,17 @@ struct nsStyleXUL {
#endif
float mBoxFlex; // [reset] see nsStyleConsts.h
PRUint32 mBoxOrdinal; // [reset] see nsStyleConsts.h
PRUint8 mBoxAlign; // [reset] see nsStyleConsts.h
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 {
nsStyleColumn();
nsStyleColumn(const nsStyleColumn& aSource);
~nsStyleColumn();
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -437,16 +437,24 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
get_computed: logical_box_prop_get_computed,
/* no subproperties */
initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
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,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "normal", "ignore", "select-all", "select-before", "select-after", "select-same", "select-menu" ],
invalid_values: []
},
--- a/layout/xul/base/src/nsStackLayout.cpp
+++ b/layout/xul/base/src/nsStackLayout.cpp
@@ -71,84 +71,91 @@ nsStackLayout::Shutdown()
{
NS_IF_RELEASE(gInstance);
}
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
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) {
+ if (child->GetStyleXUL()->mStretchStack) {
+ nsSize min = child->GetMinSize(aState);
- nsIBox* child = aBox->GetChildBox();
- while (child) {
- nsSize min = child->GetMinSize(aState);
- AddMargin(child, min);
- AddOffset(aState, child, min);
- AddLargestSize(minSize, min);
+ AddMargin(child, min);
+ AddOffset(aState, child, min);
+ AddLargestSize(minSize, min);
+ }
child = child->GetNextBox();
}
- // now add our border and padding
AddBorderAndPadding(aBox, minSize);
return minSize;
}
nsSize
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) {
+ if (child->GetStyleXUL()->mStretchStack) {
+ nsSize min = child->GetMinSize(aState);
+ nsSize max = child->GetMaxSize(aState);
- nsIBox* child = aBox->GetChildBox();
- while (child) {
- nsSize min = child->GetMinSize(aState);
- nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
+ max = nsBox::BoundsCheckMinMax(min, max);
- AddMargin(child, max);
- AddOffset(aState, child, max);
- AddSmallestSize(maxSize, 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;
}
nscoord
nsStackLayout::GetAscent(nsIBox* aBox, nsBoxLayoutState& aState)
@@ -287,25 +294,27 @@ nsStackLayout::Layout(nsIBox* aBox, nsBo
// Flow the child.
child->Layout(aState);
// Get the child's new rect.
nsRect childRectNoMargin;
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)
{
// redraw the new and old positions if the
// child moved or resized.
// if the new and old rect intersect meaning we just moved a little
// then just redraw the union. If they don't intersect (meaning
--- a/netwerk/dns/src/effective_tld_names.dat
+++ b/netwerk/dns/src/effective_tld_names.dat
@@ -1,8 +1,47 @@
+// ***** 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
edu.ac
gov.ac
net.ac
mil.ac
org.ac
--- a/xpcom/analysis/outparams.js
+++ b/xpcom/analysis/outparams.js
@@ -5,16 +5,18 @@ include('treehydra.js');
include('util.js');
include('gcc_util.js');
include('gcc_print.js');
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');
MapFactory.use_injective = true;
// Print a trace for each function analyzed
let TRACE_FUNCTIONS = 0;
// Trace operation of the ESP analysis, use 2 or 3 for more detail
@@ -143,342 +145,217 @@ function OutparamCheck(cfg, psem_list, o
this.psvar_list.push(v);
}
if (trace) {
print("PS vars");
for each (let v in this.psvar_list) {
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
function AbstractValue(name, ch) {
this.name = name;
this.ch = ch;
}
AbstractValue.prototype.equals = function(v) {
return this === v;
}
AbstractValue.prototype.toString = function() {
return this.name + ' (' + this.ch + ')';
}
+AbstractValue.prototype.toShortString = function() {
+ return this.ch;
+}
+
let avspec = [
- // General-purpose abstract values
- [ 'BOTTOM', '.' ], // any value, also used for dead vars
-
// Abstract values for outparam contents write status
[ 'NULL', 'x' ], // is a null pointer
[ 'NOT_WRITTEN', '-' ], // not written
[ 'WROTE_NULL', '/' ], // had NULL written to
[ 'WRITTEN', '+' ], // had anything written to
// MAYBE_WRITTEN is special. "Officially", it means the same thing as
// NOT_WRITTEN. What it really means is that an outparam was passed
// to another function as a possible outparam (outparam type, but not
// 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 = {};
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) {
let key = 'int_' + v;
if (cachedAVs.hasOwnProperty(key)) return cachedAVs[key];
let s = "" + v;
let ans = cachedAVs[key] = new AbstractValue(s, s);
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');
ans.outparam = v;
return ans;
}
/** Return the integer value if this is an integer av, otherwise undefined. */
av.intVal = function(v) {
if (v.hasOwnProperty('int_val'))
return v.int_val;
return undefined;
}
/** 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.
+ let values = [v1,v2]
+ if (values.indexOf(av.LOCKED) != -1
+ || values.indexOf(av.UNLOCKED) != -1)
+ return ESP.NOT_REACHED;
- // 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;
- }
-}
+ return Zero_NonZero.meet(v1, v2)
+};
// Outparam check analysis
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);
}
OutparamCheck.prototype.flowState = function(isn, state) {
switch (TREE_CODE(isn)) {
case GIMPLE_MODIFY_STMT:
this.processAssign(isn, state);
break;
case CALL_EXPR:
this.processCall(undefined, isn, isn, state);
break;
case SWITCH_EXPR:
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];
if (DECL_P(lhs)) {
// Unwrap NOP_EXPR, which is semantically a copy.
if (TREE_CODE(rhs) == NOP_EXPR) {
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();
if (DECL_P(op1) && this.outparams.has(op1) && expr_literal_int(op2) == 0) {
state.update(function(ss) {
let [s1, s2] = [ss, ss.copy()]; // s1 true, s2 false
s1.assignValue(lhs, av.NONZERO, isn);
s1.assignValue(op1, av.NULL, isn);
s2.assignValue(lhs, av.ZERO, isn);
return [s1, s2];
});
+ return;
}
}
break;
case CALL_EXPR:
let fname = call_function_name(rhs);
if (fname == 'NS_FAILED') {
this.processTest(lhs, rhs, av.NONZERO, isn, state);
} else if (fname == 'NS_SUCCEEDED') {
this.processTest(lhs, rhs, av.ZERO, isn, state);
} else if (fname == '__builtin_expect') {
// Same as an assign from arg 0 to lhs
state.assign(lhs, call_args(rhs)[0], isn);
} 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:
+ return;
+ }
- 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");
- }
+ // 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) {
state.assignValue(e, av.WROTE_NULL, isn);
} else if (DECL_P(rhs)) {
state.update(function(ss) {
let [s1, s2] = [ss.copy(), ss]; // s1 NULL, s2 non-NULL
s1.assignValue(e, av.WROTE_NULL, isn);
@@ -504,19 +381,19 @@ OutparamCheck.prototype.processAssign =
throw new Error("ni");
}
}
// Handle an assignment x := test(foo) where test is a simple predicate
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);
}
};
// The big one: outparam semantics of function calls.
OutparamCheck.prototype.processCall = function(dest, expr, blame, state) {
let args = call_args(expr);
let callable = callable_arg_function_decl(TREE_OPERAND(expr, 1));
let psem = this.func_param_semantics(callable);
@@ -645,24 +522,23 @@ OutparamCheck.prototype.check = function
}
OutparamCheck.prototype.checkSubstate = function(isvoid, fndecl, ss) {
if (isvoid) {
this.checkSubstateSuccess(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",
location_of(fndecl));
this.checkSubstateSuccess(ss);
this.checkSubstateFailure(ss);
}
}
--- a/xpcom/glue/nsDebug.h
+++ b/xpcom/glue/nsDebug.h
@@ -69,17 +69,17 @@
* NS_ABORT_IF_FALSE(0 == foo++, "yikes foo should be zero");
*
* Note also that the non-debug version of this macro does <b>not</b>
* evaluate the message argument.
*/
#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
/**
* Warn if a given condition is false.
*
* Program execution continues past the usage of this macro.
*