зеркало из https://github.com/mozilla/pjs.git
Merge mozilla-central to tabcandy-central.
This commit is contained in:
Коммит
038e101e68
|
@ -4,6 +4,8 @@ skin testpilot skin skin/all/
|
|||
skin testpilot-os skin skin/linux/ os=Linux
|
||||
skin testpilot-os skin skin/mac/ os=Darwin
|
||||
skin testpilot-os skin skin/win/ os=WINNT
|
||||
overlay chrome://browser/content/macBrowserOverlay.xul chrome://testpilot/content/tp-browser.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} appversion<4.0b1pre
|
||||
overlay chrome://browser/content/macBrowserOverlay.xul chrome://testpilot/content/feedback-browser.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} appversion>=4.0b1pre
|
||||
overlay chrome://browser/content/browser.xul chrome://testpilot/content/tp-browser.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} appversion<=3.6.*
|
||||
overlay chrome://browser/content/browser.xul chrome://testpilot/content/feedback-browser.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} appversion>3.7a1pre
|
||||
# For the menubar on Mac
|
||||
|
|
|
@ -286,11 +286,9 @@ var TestPilotXulWindow = {
|
|||
let openInTab = (task.taskType == TaskConstants.TYPE_LEGACY);
|
||||
|
||||
this.addDescription(textVbox, task.title, task.summary);
|
||||
if (task.showMoreInfoLink) {
|
||||
this.addXulLink(
|
||||
textVbox, this._stringBundle.getString("testpilot.moreInfo"),
|
||||
task.defaultUrl, openInTab);
|
||||
}
|
||||
this.addXulLink(
|
||||
textVbox, this._stringBundle.getString("testpilot.moreInfo"),
|
||||
task.defaultUrl, openInTab);
|
||||
|
||||
// Create the rightmost status area, depending on status:
|
||||
let statusVbox = document.createElement("vbox");
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
#feedback-menu-button .toolbarbutton-text {
|
||||
display: -moz-box;
|
||||
margin: 0;
|
||||
color: -moz-dialogtext;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
#feedback-menu-button .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -166,10 +166,6 @@ var TestPilotTask = {
|
|||
return url + this._id;
|
||||
},
|
||||
|
||||
get showMoreInfoLink() {
|
||||
return true;
|
||||
},
|
||||
|
||||
// event handlers:
|
||||
|
||||
onExperimentStartup: function TestPilotTask_onExperimentStartup() {
|
||||
|
@ -1021,10 +1017,6 @@ TestPilotWebSurvey.prototype = {
|
|||
return this.infoPageUrl;
|
||||
},
|
||||
|
||||
get showMoreInfoLink() {
|
||||
return false;
|
||||
},
|
||||
|
||||
onDetailPageOpened: function TPWS_onDetailPageOpened() {
|
||||
/* Once you view the URL of the survey, we'll assume you've taken it.
|
||||
* There's no reliable way to tell whether you have or not, so let's
|
||||
|
|
|
@ -6777,14 +6777,12 @@ var gBookmarkAllTabsHandler = {
|
|||
this._updateCommandState();
|
||||
},
|
||||
|
||||
_updateCommandState: function BATH__updateCommandState(aTabClose) {
|
||||
let numTabs = gBrowser.visibleTabs.length;
|
||||
_updateCommandState: function BATH__updateCommandState() {
|
||||
let remainingTabs = gBrowser.visibleTabs.filter(function(tab) {
|
||||
return gBrowser._removingTabs.indexOf(tab) == -1;
|
||||
});
|
||||
|
||||
// The TabClose event is fired before the tab is removed from the DOM
|
||||
if (aTabClose)
|
||||
numTabs--;
|
||||
|
||||
if (numTabs > 1)
|
||||
if (remainingTabs.length > 1)
|
||||
this._command.removeAttribute("disabled");
|
||||
else
|
||||
this._command.setAttribute("disabled", "true");
|
||||
|
@ -6796,7 +6794,7 @@ var gBookmarkAllTabsHandler = {
|
|||
|
||||
// nsIDOMEventListener
|
||||
handleEvent: function(aEvent) {
|
||||
this._updateCommandState(aEvent.type == "TabClose");
|
||||
this._updateCommandState();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1025,7 +1025,8 @@
|
|||
// == 1 false YES
|
||||
// == 1 true NO
|
||||
// > 1 false/true NO
|
||||
var owner = (aURIs.length > 1) || aLoadInBackground ? null : this.selectedTab;
|
||||
var multiple = aURIs.length > 1;
|
||||
var owner = multiple || aLoadInBackground ? null : this.selectedTab;
|
||||
var firstTabAdded = null;
|
||||
|
||||
if (aReplace) {
|
||||
|
@ -1037,7 +1038,7 @@
|
|||
}
|
||||
}
|
||||
else
|
||||
firstTabAdded = this.addTab(aURIs[0], {ownerTab: owner, skipAnimation: true});
|
||||
firstTabAdded = this.addTab(aURIs[0], {ownerTab: owner, skipAnimation: multiple});
|
||||
|
||||
var tabNum = this.tabContainer.selectedIndex;
|
||||
for (let i = 1; i < aURIs.length; ++i) {
|
||||
|
@ -1333,10 +1334,19 @@
|
|||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
|
||||
if (aParams)
|
||||
var animate = aParams.animate;
|
||||
|
||||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
if (!animate &&
|
||||
this._removingTabs.indexOf(aTab) > -1) {
|
||||
this._endRemoveTab(aTab);
|
||||
return;
|
||||
}
|
||||
|
||||
var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
|
||||
|
||||
if (!this._beginRemoveTab(aTab, false, null, true))
|
||||
return;
|
||||
|
||||
|
@ -1576,12 +1586,15 @@
|
|||
}
|
||||
|
||||
let removing = this._removingTabs;
|
||||
let ignoreRemoving = function(tab) removing.indexOf(tab) == -1;
|
||||
function keepRemaining(tab) {
|
||||
// A tab remains only if it's not being removed nor blurred
|
||||
return removing.indexOf(tab) == -1 && tab != aTab;
|
||||
}
|
||||
|
||||
// Switch to a visible tab unless there aren't any remaining
|
||||
let remainingTabs = this.visibleTabs.filter(ignoreRemoving);
|
||||
let remainingTabs = this.visibleTabs.filter(keepRemaining);
|
||||
if (remainingTabs.length == 0)
|
||||
remainingTabs = Array.filter(this.tabs, ignoreRemoving);
|
||||
remainingTabs = Array.filter(this.tabs, keepRemaining);
|
||||
|
||||
// Try to find a remaining tab that comes after the given tab
|
||||
var tab = aTab;
|
||||
|
@ -1589,8 +1602,15 @@
|
|||
tab = tab.nextSibling;
|
||||
} while (tab && remainingTabs.indexOf(tab) == -1);
|
||||
|
||||
// If no tab was found, give the end of the remaining tabs
|
||||
this.selectedTab = tab ? tab : remainingTabs.pop();
|
||||
if (!tab) {
|
||||
tab = aTab;
|
||||
|
||||
do {
|
||||
tab = tab.previousSibling;
|
||||
} while (tab && remainingTabs.indexOf(tab) == -1);
|
||||
}
|
||||
|
||||
this.selectedTab = tab;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -1786,11 +1806,8 @@
|
|||
if (aIndex < 0)
|
||||
aIndex += tabs.length;
|
||||
|
||||
if (aIndex >= 0 && aIndex < tabs.length) {
|
||||
let nextTab = tabs[aIndex];
|
||||
if (nextTab != this.selectedTab)
|
||||
this.selectedTab = nextTab;
|
||||
}
|
||||
if (aIndex >= 0 && aIndex < tabs.length)
|
||||
this.selectedTab = tabs[aIndex];
|
||||
|
||||
if (aEvent) {
|
||||
aEvent.preventDefault();
|
||||
|
@ -2417,9 +2434,9 @@
|
|||
</method>
|
||||
<method name="_canScrollToElement">
|
||||
<parameter name="tab"/>
|
||||
<body>
|
||||
return !tab.pinned;
|
||||
</body>
|
||||
<body><![CDATA[
|
||||
return !tab.pinned && !tab.hidden;
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
|
@ -2431,7 +2448,7 @@
|
|||
var tabs = document.getBindingParent(this);
|
||||
tabs.removeAttribute("overflow");
|
||||
|
||||
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser._endRemoveTab,
|
||||
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
|
||||
tabs.tabbrowser);
|
||||
|
||||
tabs._positionPinnedTabs();
|
||||
|
@ -2596,9 +2613,8 @@
|
|||
if (this.childNodes.length == 1 && this._closeWindowWithLastTab)
|
||||
this.setAttribute("closebuttons", "noclose");
|
||||
else {
|
||||
let tab = this.childNodes.item(this.tabbrowser._numPinnedTabs);
|
||||
if (tab && tab.hidden)
|
||||
tab = this.tabbrowser.visibleTabs[0];
|
||||
// Grab the last tab for size comparison
|
||||
let tab = this.tabbrowser.visibleTabs.pop();
|
||||
if (tab && tab.getBoundingClientRect().width > this.mTabClipWidth)
|
||||
this.setAttribute("closebuttons", "alltabs");
|
||||
else
|
||||
|
|
|
@ -5,6 +5,11 @@ function test() {
|
|||
gBrowser.removeTab(tab);
|
||||
is(tab.parentNode, null, "tab removed immediately");
|
||||
|
||||
tab = gBrowser.addTab("about:blank", { skipAnimation: true });
|
||||
gBrowser.removeTab(tab, { animate: true });
|
||||
gBrowser.removeTab(tab);
|
||||
is(tab.parentNode, null, "tab removed immediately when calling removeTab again after the animation was kicked off");
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref("browser.tabs.animate", true);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Edward Lee <edilee@mozilla.com>
|
||||
* Edward Lee <edilee@mozilla.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -115,6 +115,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_524745.js \
|
||||
browser_528776.js \
|
||||
browser_579879.js \
|
||||
browser_586147.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* ***** 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 sessionstore test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Edward Lee <edilee@mozilla.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
function observeOneRestore(callback) {
|
||||
let topic = "sessionstore-browser-state-restored";
|
||||
Services.obs.addObserver(function() {
|
||||
Services.obs.removeObserver(arguments.callee, topic, false);
|
||||
callback();
|
||||
}, topic, false);
|
||||
};
|
||||
|
||||
function test() {
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
waitForExplicitFinish();
|
||||
|
||||
// There should be one tab when we start the test
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
let hiddenTab = gBrowser.addTab();
|
||||
|
||||
is(gBrowser.visibleTabs.length, 2, "should have 2 tabs before hiding");
|
||||
gBrowser.showOnlyTheseTabs([origTab]);
|
||||
is(gBrowser.visibleTabs.length, 1, "only 1 after hiding");
|
||||
ok(hiddenTab.hidden, "sanity check that it's hidden");
|
||||
|
||||
let extraTab = gBrowser.addTab();
|
||||
let state = ss.getBrowserState();
|
||||
let stateObj = JSON.parse(state);
|
||||
let tabs = stateObj.windows[0].tabs;
|
||||
is(tabs.length, 3, "just checking that browser state is correct");
|
||||
ok(!tabs[0].hidden, "first tab is visible");
|
||||
ok(tabs[1].hidden, "second is hidden");
|
||||
ok(!tabs[2].hidden, "third is visible");
|
||||
|
||||
// Make the third tab hidden and then restore the modified state object
|
||||
tabs[2].hidden = true;
|
||||
|
||||
observeOneRestore(function() {
|
||||
let testWindow = Services.wm.getEnumerator("navigator:browser").getNext();
|
||||
is(testWindow.gBrowser.visibleTabs.length, 1, "only restored 1 visible tab");
|
||||
let tabs = testWindow.gBrowser.tabs;
|
||||
ok(!tabs[0].hidden, "first is still visible");
|
||||
ok(tabs[1].hidden, "second tab is still hidden");
|
||||
ok(tabs[2].hidden, "third tab is now hidden");
|
||||
|
||||
// Restore the original state and clean up now that we're done
|
||||
gBrowser.removeTab(hiddenTab);
|
||||
gBrowser.removeTab(extraTab);
|
||||
finish();
|
||||
});
|
||||
ss.setBrowserState(JSON.stringify(stateObj));
|
||||
}
|
|
@ -11,9 +11,9 @@
|
|||
@DLL_PREFIX@zlib@DLL_SUFFIX@
|
||||
LICENSE
|
||||
browserconfig.properties
|
||||
chrome.manifest
|
||||
chrome/US.jar
|
||||
chrome/app-chrome.manifest
|
||||
chrome/browser.manifest
|
||||
chrome/chrome.rdf
|
||||
chrome/chromelist.txt
|
||||
chrome/classic.jar
|
||||
|
@ -21,14 +21,18 @@ chrome/classic.manifest
|
|||
chrome/comm.jar
|
||||
chrome/comm.manifest
|
||||
chrome/en-win.jar
|
||||
chrome/en-US.manifest
|
||||
chrome/help.jar
|
||||
chrome/installed-chrome.txt
|
||||
chrome/m3ffxtbr.jar
|
||||
chrome/m3ffxtbr.manifest
|
||||
chrome/overlayinfo/
|
||||
chrome/pippki.manifest
|
||||
chrome/reporter.jar
|
||||
chrome/reporter.manifest
|
||||
chrome/toolkit.manifest
|
||||
component.reg
|
||||
components/browser.manifest
|
||||
components/components.list
|
||||
components/@DLL_PREFIX@browserdirprovider@DLL_SUFFIX@
|
||||
components/@DLL_PREFIX@brwsrdir@DLL_SUFFIX@
|
||||
|
|
|
@ -882,7 +882,7 @@ toolbar[iconsize="small"] #fullscreen-button {
|
|||
-moz-border-start: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
#identity-box:focus {
|
||||
#identity-box:-moz-focusring {
|
||||
outline: 1px dotted -moz-DialogText;
|
||||
}
|
||||
|
||||
|
|
|
@ -705,7 +705,7 @@ toolbar[iconsize="small"][mode="icons"] #forward-button:-moz-locale-dir(rtl) {
|
|||
}
|
||||
|
||||
|
||||
#identity-box:focus:not(:active):not([open="true"]) {
|
||||
#identity-box:-moz-focusring {
|
||||
-moz-box-shadow: 0 0 3px 1px -moz-mac-focusring inset,
|
||||
0 0 3px 2px -moz-mac-focusring;
|
||||
}
|
||||
|
|
|
@ -60,11 +60,8 @@
|
|||
|
||||
#navigator-toolbox {
|
||||
-moz-appearance: none;
|
||||
border-top: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#navigator-toolbox[tabsontop="true"] {
|
||||
border-top: none;
|
||||
border-bottom: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
|
@ -81,7 +78,11 @@
|
|||
}
|
||||
|
||||
#nav-bar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[tabsontop="true"] > #nav-bar {
|
||||
#nav-bar[collapsed="true"] + toolbar:not(:-moz-lwtheme),
|
||||
#nav-bar[collapsed="true"] + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[tabsontop="true"] > #nav-bar,
|
||||
#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + toolbar,
|
||||
#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + #customToolbars + #PersonalToolbar {
|
||||
background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
|
@ -850,13 +851,13 @@ toolbar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="tru
|
|||
background-color: hsl(92,45%,52%);
|
||||
}
|
||||
|
||||
#identity-box:focus {
|
||||
#identity-box:-moz-focusring {
|
||||
outline: 1px dotted -moz-DialogText;
|
||||
outline-offset: -3px;
|
||||
}
|
||||
|
||||
#identity-box.verifiedDomain:focus ,
|
||||
#identity-box.verifiedIdentity:focus {
|
||||
#identity-box.verifiedDomain:-moz-focusring,
|
||||
#identity-box.verifiedIdentity:-moz-focusring {
|
||||
outline-color: white;
|
||||
}
|
||||
|
||||
|
@ -1121,10 +1122,6 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
|||
-moz-box-shadow: 0 -1px ThreeDShadow inset;
|
||||
}
|
||||
|
||||
#TabsToolbar[tabsontop="false"] {
|
||||
border-bottom: 1px solid ThreeDShadow !important;
|
||||
}
|
||||
|
||||
.tabbrowser-tabs:-moz-system-metric(touch-enabled) {
|
||||
min-height: .73cm;
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ public:
|
|||
nsIViewManager* aViewManager,
|
||||
nsStyleSet* aStyleSet,
|
||||
nsIPresShell** aInstancePtrResult) = 0;
|
||||
void DeleteShell() { mPresShell = nsnull; }
|
||||
virtual void DeleteShell() = 0;
|
||||
|
||||
nsIPresShell* GetShell() const
|
||||
{
|
||||
|
|
|
@ -249,7 +249,7 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
|
|||
case eAtomArray:
|
||||
{
|
||||
if (!EnsureEmptyAtomArray() ||
|
||||
!GetAtomArrayValue()->AppendObjects(*otherCont->mAtomArray)) {
|
||||
!GetAtomArrayValue()->AppendElements(*otherCont->mAtomArray)) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ nsAttrValue::GetEnumString(nsAString& aResult, PRBool aRealTag) const
|
|||
NS_NOTREACHED("couldn't find value in EnumTable");
|
||||
}
|
||||
|
||||
PRInt32
|
||||
PRUint32
|
||||
nsAttrValue::GetAtomCount() const
|
||||
{
|
||||
ValueType type = Type();
|
||||
|
@ -513,7 +513,7 @@ nsAttrValue::GetAtomCount() const
|
|||
}
|
||||
|
||||
if (type == eAtomArray) {
|
||||
return GetAtomArrayValue()->Count();
|
||||
return GetAtomArrayValue()->Length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -531,7 +531,7 @@ nsAttrValue::AtomAt(PRInt32 aIndex) const
|
|||
|
||||
NS_ASSERTION(Type() == eAtomArray, "GetAtomCount must be confused");
|
||||
|
||||
return GetAtomArrayValue()->ObjectAt(aIndex);
|
||||
return GetAtomArrayValue()->ElementAt(aIndex);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
@ -592,9 +592,11 @@ nsAttrValue::HashValue() const
|
|||
case eAtomArray:
|
||||
{
|
||||
PRUint32 retval = 0;
|
||||
PRInt32 i, count = cont->mAtomArray->Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
retval ^= NS_PTR_TO_INT32(cont->mAtomArray->ObjectAt(i));
|
||||
PRUint32 count = cont->mAtomArray->Length();
|
||||
for (nsCOMPtr<nsIAtom> *cur = cont->mAtomArray->Elements(),
|
||||
*end = cur + count;
|
||||
cur != end; ++cur) {
|
||||
retval ^= NS_PTR_TO_INT32(cur->get());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -690,18 +692,10 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
|||
// For classlists we could be insensitive to order, however
|
||||
// classlists are never mapped attributes so they are never compared.
|
||||
|
||||
PRInt32 count = thisCont->mAtomArray->Count();
|
||||
if (count != otherCont->mAtomArray->Count()) {
|
||||
if (!(*thisCont->mAtomArray == *otherCont->mAtomArray)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (thisCont->mAtomArray->ObjectAt(i) !=
|
||||
otherCont->mAtomArray->ObjectAt(i)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
needsStringComparison = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -827,19 +821,21 @@ nsAttrValue::Contains(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const
|
|||
default:
|
||||
{
|
||||
if (Type() == eAtomArray) {
|
||||
nsCOMArray<nsIAtom>* array = GetAtomArrayValue();
|
||||
AtomArray* array = GetAtomArrayValue();
|
||||
if (aCaseSensitive == eCaseMatters) {
|
||||
return array->IndexOf(aValue) >= 0;
|
||||
return array->IndexOf(aValue) != AtomArray::NoIndex;
|
||||
}
|
||||
|
||||
nsDependentAtomString val1(aValue);
|
||||
|
||||
for (PRInt32 i = 0, count = array->Count(); i < count; ++i) {
|
||||
for (nsCOMPtr<nsIAtom> *cur = array->Elements(),
|
||||
*end = cur + array->Length();
|
||||
cur != end; ++cur) {
|
||||
// For performance reasons, don't do a full on unicode case
|
||||
// insensitive string comparison. This is only used for quirks mode
|
||||
// anyway.
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(val1,
|
||||
nsDependentAtomString(array->ObjectAt(i)))) {
|
||||
nsDependentAtomString(*cur))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -913,9 +909,9 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIAtom>* array = GetAtomArrayValue();
|
||||
AtomArray* array = GetAtomArrayValue();
|
||||
|
||||
if (!array->AppendObject(classAtom)) {
|
||||
if (!array->AppendElement(classAtom)) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
@ -930,7 +926,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
|||
|
||||
classAtom = do_GetAtom(Substring(start, iter));
|
||||
|
||||
if (!array->AppendObject(classAtom)) {
|
||||
if (!array->AppendElement(classAtom)) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
@ -1362,7 +1358,7 @@ nsAttrValue::EnsureEmptyAtomArray()
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIAtom>* array = new nsCOMArray<nsIAtom>;
|
||||
AtomArray* array = new AtomArray;
|
||||
if (!array) {
|
||||
Reset();
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsColor.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
typedef PRUptrdiff PtrBits;
|
||||
class nsAString;
|
||||
|
@ -57,7 +58,7 @@ class nsIAtom;
|
|||
class nsICSSStyleRule;
|
||||
class nsISVGValue;
|
||||
class nsIDocument;
|
||||
template<class E> class nsCOMArray;
|
||||
template<class E> class nsTArray;
|
||||
template<class E> class nsTPtrArray;
|
||||
|
||||
#define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
|
||||
|
@ -92,6 +93,8 @@ public:
|
|||
|
||||
class nsAttrValue {
|
||||
public:
|
||||
typedef nsTArray< nsCOMPtr<nsIAtom> > AtomArray;
|
||||
|
||||
nsAttrValue();
|
||||
nsAttrValue(const nsAttrValue& aOther);
|
||||
explicit nsAttrValue(const nsAString& aValue);
|
||||
|
@ -151,7 +154,7 @@ public:
|
|||
PRBool GetColorValue(nscolor& aColor) const;
|
||||
inline PRInt16 GetEnumValue() const;
|
||||
inline float GetPercentValue() const;
|
||||
inline nsCOMArray<nsIAtom>* GetAtomArrayValue() const;
|
||||
inline AtomArray* GetAtomArrayValue() const;
|
||||
inline nsICSSStyleRule* GetCSSStyleRuleValue() const;
|
||||
#ifdef MOZ_SVG
|
||||
inline nsISVGValue* GetSVGValue() const;
|
||||
|
@ -170,7 +173,7 @@ public:
|
|||
// Methods to get access to atoms we may have
|
||||
// Returns the number of atoms we have; 0 if we have none. It's OK
|
||||
// to call this without checking the type first; it handles that.
|
||||
PRInt32 GetAtomCount() const;
|
||||
PRUint32 GetAtomCount() const;
|
||||
// Returns the atom at aIndex (0-based). Do not call this with
|
||||
// aIndex >= GetAtomCount().
|
||||
nsIAtom* AtomAt(PRInt32 aIndex) const;
|
||||
|
@ -333,7 +336,7 @@ private:
|
|||
PRUint32 mEnumValue;
|
||||
PRInt32 mPercent;
|
||||
nsICSSStyleRule* mCSSStyleRule;
|
||||
nsCOMArray<nsIAtom>* mAtomArray;
|
||||
AtomArray* mAtomArray;
|
||||
#ifdef MOZ_SVG
|
||||
nsISVGValue* mSVGValue;
|
||||
#endif
|
||||
|
@ -426,7 +429,7 @@ nsAttrValue::GetPercentValue() const
|
|||
/ 100.0f;
|
||||
}
|
||||
|
||||
inline nsCOMArray<nsIAtom>*
|
||||
inline nsAttrValue::AtomArray*
|
||||
nsAttrValue::GetAtomArrayValue() const
|
||||
{
|
||||
NS_PRECONDITION(Type() == eAtomArray, "wrong type");
|
||||
|
|
|
@ -6004,7 +6004,7 @@ nsContentUtils::ReparentClonedObjectToScope(JSContext* cx,
|
|||
}
|
||||
|
||||
struct ClassMatchingInfo {
|
||||
nsCOMArray<nsIAtom> mClasses;
|
||||
nsAttrValue::AtomArray mClasses;
|
||||
nsCaseTreatment mCaseTreatment;
|
||||
};
|
||||
|
||||
|
@ -6020,14 +6020,14 @@ MatchClassNames(nsIContent* aContent, PRInt32 aNamespaceID, nsIAtom* aAtom,
|
|||
|
||||
// need to match *all* of the classes
|
||||
ClassMatchingInfo* info = static_cast<ClassMatchingInfo*>(aData);
|
||||
PRInt32 length = info->mClasses.Count();
|
||||
PRUint32 length = info->mClasses.Length();
|
||||
if (!length) {
|
||||
// If we actually had no classes, don't match.
|
||||
return PR_FALSE;
|
||||
}
|
||||
PRInt32 i;
|
||||
PRUint32 i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (!classAttr->Contains(info->mClasses.ObjectAt(i),
|
||||
if (!classAttr->Contains(info->mClasses[i],
|
||||
info->mCaseTreatment)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -6054,9 +6054,9 @@ AllocClassMatchingInfo(nsINode* aRootNode,
|
|||
NS_ENSURE_TRUE(info, nsnull);
|
||||
|
||||
if (attrValue.Type() == nsAttrValue::eAtomArray) {
|
||||
info->mClasses.AppendObjects(*(attrValue.GetAtomArrayValue()));
|
||||
info->mClasses.SwapElements(*(attrValue.GetAtomArrayValue()));
|
||||
} else if (attrValue.Type() == nsAttrValue::eAtom) {
|
||||
info->mClasses.AppendObject(attrValue.GetAtomValue());
|
||||
info->mClasses.AppendElement(attrValue.GetAtomValue());
|
||||
}
|
||||
|
||||
info->mCaseTreatment =
|
||||
|
|
|
@ -783,6 +783,36 @@ nsExternalResourceMap::Traverse(nsCycleCollectionTraversalCallback* aCallback) c
|
|||
mMap.EnumerateRead(ExternalResourceTraverser, aCallback);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ExternalResourceHider(nsIURI* aKey,
|
||||
nsExternalResourceMap::ExternalResource* aData,
|
||||
void* aClosure)
|
||||
{
|
||||
aData->mViewer->Hide();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsExternalResourceMap::HideViewers()
|
||||
{
|
||||
mMap.EnumerateRead(ExternalResourceHider, nsnull);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ExternalResourceShower(nsIURI* aKey,
|
||||
nsExternalResourceMap::ExternalResource* aData,
|
||||
void* aClosure)
|
||||
{
|
||||
aData->mViewer->Show();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsExternalResourceMap::ShowViewers()
|
||||
{
|
||||
mMap.EnumerateRead(ExternalResourceShower, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsExternalResourceMap::AddExternalResource(nsIURI* aURI,
|
||||
nsIDocumentViewer* aViewer,
|
||||
|
@ -811,6 +841,9 @@ nsExternalResourceMap::AddExternalResource(nsIURI* aURI,
|
|||
} else {
|
||||
doc->SetDisplayDocument(aDisplayDocument);
|
||||
|
||||
// Make sure that hiding our viewer will tear down its presentation.
|
||||
aViewer->SetSticky(PR_FALSE);
|
||||
|
||||
rv = aViewer->Init(nsnull, nsIntRect(0, 0, 0, 0));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = aViewer->Open(nsnull, nsnull);
|
||||
|
@ -3039,11 +3072,20 @@ nsDocument::doCreateShell(nsPresContext* aContext,
|
|||
// Note: we don't hold a ref to the shell (it holds a ref to us)
|
||||
mPresShell = shell;
|
||||
|
||||
mExternalResourceMap.ShowViewers();
|
||||
|
||||
shell.swap(*aInstancePtrResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::DeleteShell()
|
||||
{
|
||||
mExternalResourceMap.HideViewers();
|
||||
mPresShell = nsnull;
|
||||
}
|
||||
|
||||
static void
|
||||
SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
{
|
||||
|
@ -7815,4 +7857,3 @@ nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
|
|||
mCreatingStaticClone = PR_FALSE;
|
||||
return clonedDoc.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -375,6 +375,12 @@ public:
|
|||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
};
|
||||
|
||||
// Hide all our viewers
|
||||
void HideViewers();
|
||||
|
||||
// Show all our viewers
|
||||
void ShowViewers();
|
||||
|
||||
protected:
|
||||
class PendingLoad : public ExternalResourceLoad,
|
||||
public nsIStreamListener
|
||||
|
@ -588,6 +594,7 @@ public:
|
|||
nsIViewManager* aViewManager,
|
||||
nsStyleSet* aStyleSet,
|
||||
nsIPresShell** aInstancePtrResult);
|
||||
virtual void DeleteShell();
|
||||
|
||||
virtual nsresult SetSubDocumentFor(nsIContent *aContent,
|
||||
nsIDocument* aSubDoc);
|
||||
|
|
|
@ -1100,6 +1100,10 @@ nsHTMLParanoidFragmentSink::CloseContainer(const nsHTMLTag aTag)
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mIgnoreNextCloseHead && aTag == eHTMLTag_head) {
|
||||
mIgnoreNextCloseHead = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (mSkip) {
|
||||
mSkip = PR_FALSE;
|
||||
return rv;
|
||||
|
@ -1229,7 +1233,10 @@ nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode)
|
|||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mSkip) {
|
||||
// We need to explicitly skip adding leaf nodes in the paranoid sink,
|
||||
// otherwise things like the textnode under <title> get appended to
|
||||
// the fragment itself, and won't be popped off in CloseContainer.
|
||||
if (mSkip || mIgnoreNextCloseHead) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=520182
|
|||
<div id="jj" contenteditable="true"></div>
|
||||
<iframe id="kk" src="about:blank"></iframe>
|
||||
<div id="ll" contenteditable="true"></div>
|
||||
<iframe id="mm" src="about:blank"></iframe>
|
||||
<div id="nn" contenteditable="true"></div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
@ -73,6 +75,7 @@ const invalidStyle3Payload = "foo<style>@import 'xxx.css';</style>baz";
|
|||
const invalidStyle4Payload = "foo<span style=\"@import 'xxx.css';\">bar</span>baz";
|
||||
const invalidStyle5Payload = "foo<span style=\"@font-face{font-family:xxx;src:'xxx.ttf';}\">bar</span>baz";
|
||||
const invalidStyle6Payload = "foo<span style=\"@namespace xxx url(http://example.com/);\">bar</span>baz";
|
||||
const invalidStyle7Payload = "<html><head><title>xxx</title></head><body>foo</body></html>";
|
||||
const nestedStylePayload = "foo<style>#bar1{-moz-binding:url('data:text/xml,<?xml version="1.0"><binding xmlns="http://www.mozilla.org/xbl" id="binding-1"/>');<style></style>#bar2{-moz-binding:url('data:text/xml,<?xml version="1.0"><binding xmlns="http://www.mozilla.org/xbl" id="binding-2"/>');</style>baz";
|
||||
const validImgSrc1Payload = "foo<img src=\"data:image/png,bar\">baz";
|
||||
const validImgSrc2Payload = "foo<img src=\"javascript:void('bar');\">baz";
|
||||
|
@ -333,6 +336,27 @@ var tests = [
|
|||
payload: invalidStyle6Payload,
|
||||
rootElement: function() document.getElementById("ll"),
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "mm",
|
||||
isIFrame: true,
|
||||
insertHTML: true,
|
||||
payload: invalidStyle7Payload,
|
||||
rootElement: function() document.getElementById("mm").contentDocument.documentElement,
|
||||
checkResult: function(html) {
|
||||
is(html.indexOf("xxx"), -1, "Should not have retained the title text");
|
||||
isnot(html.indexOf("foo"), -1, "Should have retained the body text");
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "nn",
|
||||
insertHTML: true,
|
||||
payload: invalidStyle7Payload,
|
||||
rootElement: function() document.getElementById("nn"),
|
||||
checkResult: function(html) {
|
||||
is(html.indexOf("xxx"), -1, "Should not have retained the title text");
|
||||
isnot(html.indexOf("foo"), -1, "Should have retained the body text");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -357,28 +381,37 @@ function runTest(test) {
|
|||
} else
|
||||
elem.focus();
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
if ("insertHTML" in test) {
|
||||
if ("isIFrame" in test) {
|
||||
elem.contentDocument.execCommand("inserthtml", false, test.payload);
|
||||
} else {
|
||||
getSelection().collapse(elem, 0);
|
||||
document.execCommand("inserthtml", false, test.payload);
|
||||
}
|
||||
} else {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
var data = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
data.data = test.payload;
|
||||
trans.addDataFlavor("text/html");
|
||||
trans.setTransferData("text/html", data, data.data.length * 2);
|
||||
clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
var data = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
data.data = test.payload;
|
||||
trans.addDataFlavor("text/html");
|
||||
trans.setTransferData("text/html", data, data.data.length * 2);
|
||||
clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
|
||||
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
|
||||
mainWindow.goDoCommand("cmd_paste");
|
||||
mainWindow.goDoCommand("cmd_paste");
|
||||
}
|
||||
|
||||
if ("checkResult" in test) {
|
||||
if ("isIFrame" in test) {
|
||||
|
|
|
@ -214,7 +214,7 @@ cairo_d2d_create_device()
|
|||
D3D10_1_SDK_VERSION,
|
||||
&device->mD3D10Device);
|
||||
if (FAILED(hr)) {
|
||||
HRESULT hr = createD3DDevice(
|
||||
hr = createD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
|
@ -225,7 +225,7 @@ cairo_d2d_create_device()
|
|||
&device->mD3D10Device);
|
||||
if (FAILED(hr)) {
|
||||
/* This is not guaranteed to be too fast! */
|
||||
HRESULT hr = createD3DDevice(
|
||||
hr = createD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
|
|
|
@ -1115,12 +1115,12 @@ xpc_qsXPCOMObjectToJsval(XPCLazyCallContext &lccx, qsObjectHelper* aHelper,
|
|||
const nsIID *iid, XPCNativeInterface **iface,
|
||||
jsval *rval)
|
||||
{
|
||||
NS_PRECONDITION(iface, "Who did that and why?");
|
||||
|
||||
// From the T_INTERFACE case in XPCConvert::NativeData2JS.
|
||||
// This is one of the slowest things quick stubs do.
|
||||
|
||||
JSContext *cx = lccx.GetJSContext();
|
||||
if(!iface)
|
||||
return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_CONVERT_NATIVE);
|
||||
|
||||
// XXX The OBJ_IS_NOT_GLOBAL here is not really right. In
|
||||
// fact, this code is depending on the fact that the
|
||||
|
|
|
@ -860,7 +860,9 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
|
|||
// it in one place (Show()) and require that callers call init(), open(),
|
||||
// show() in that order or something.
|
||||
if (!mPresContext &&
|
||||
(aParentWidget || containerView || mDocument->GetDisplayDocument())) {
|
||||
(aParentWidget || containerView ||
|
||||
(mDocument->GetDisplayDocument() &&
|
||||
mDocument->GetDisplayDocument()->GetShell()))) {
|
||||
// Create presentation context
|
||||
if (mIsPageMode) {
|
||||
//Presentation context already created in SetPageMode which is calling this method
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
namespace css = mozilla::css;
|
||||
|
||||
/**
|
||||
* A namespace class for static layout utilities.
|
||||
|
@ -1752,6 +1753,15 @@ static nscoord AddPercents(nsLayoutUtils::IntrinsicWidthType aType,
|
|||
|
||||
static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, nscoord& aResult)
|
||||
{
|
||||
if (aStyle.IsCalcUnit()) {
|
||||
if (aStyle.CalcHasPercent()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
// If it has no percents, we can pass 0 for the percentage basis.
|
||||
aResult = nsRuleNode::ComputeComputedCalc(aStyle, 0);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (eStyleUnit_Coord != aStyle.GetUnit())
|
||||
return PR_FALSE;
|
||||
|
||||
|
@ -2036,12 +2046,21 @@ nsLayoutUtils::IntrinsicForContainer(nsIRenderingContext *aRenderingContext,
|
|||
PROP_WIDTH, w)) {
|
||||
result = AddPercents(aType, w + coordOutsideWidth, pctOutsideWidth);
|
||||
}
|
||||
else if (aType == MIN_WIDTH && eStyleUnit_Percent == styleWidth.GetUnit() &&
|
||||
else if (aType == MIN_WIDTH &&
|
||||
// The only cases of coord-percent-calc() units that
|
||||
// GetAbsoluteCoord didn't handle are percent and calc()s
|
||||
// containing percent.
|
||||
styleWidth.IsCoordPercentCalcUnit() &&
|
||||
aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
|
||||
// A percentage width on replaced elements means they can shrink to 0.
|
||||
result = 0; // let |min| handle padding/border/margin
|
||||
}
|
||||
else {
|
||||
// NOTE: We could really do a lot better for percents and for some
|
||||
// cases of calc() containing percent (certainly including any where
|
||||
// the coefficient on the percent is positive and there are no max()
|
||||
// expressions). However, doing better for percents wouldn't be
|
||||
// backwards compatible.
|
||||
result = AddPercents(aType, result, pctTotal);
|
||||
}
|
||||
|
||||
|
@ -2138,15 +2157,12 @@ nsLayoutUtils::ComputeWidthValue(
|
|||
"width less than zero");
|
||||
|
||||
nscoord result;
|
||||
if (eStyleUnit_Coord == aCoord.GetUnit()) {
|
||||
result = aCoord.GetCoordValue();
|
||||
NS_ASSERTION(result >= 0, "width less than zero");
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
result = nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockWidth);
|
||||
// The result of a calc() expression might be less than 0; we
|
||||
// should clamp at runtime (below). (Percentages and coords that
|
||||
// are less than 0 have already been dropped by the parser.)
|
||||
result -= aContentEdgeToBoxSizing;
|
||||
} else if (eStyleUnit_Percent == aCoord.GetUnit()) {
|
||||
NS_ASSERTION(aCoord.GetPercentValue() >= 0.0f, "width less than zero");
|
||||
result = NSToCoordFloorClamped(aContainingBlockWidth *
|
||||
aCoord.GetPercentValue()) -
|
||||
aContentEdgeToBoxSizing;
|
||||
} else if (eStyleUnit_Enumerated == aCoord.GetUnit()) {
|
||||
PRInt32 val = aCoord.GetIntValue();
|
||||
switch (val) {
|
||||
|
|
|
@ -226,29 +226,9 @@ static inline PRBool IsFixedPaddingSize(nsStyleUnit aUnit) {
|
|||
static inline PRBool IsFixedMarginSize(nsStyleUnit aUnit) {
|
||||
return aUnit == eStyleUnit_Coord;
|
||||
}
|
||||
static inline PRBool IsFixedMaxSize(nsStyleUnit aUnit) {
|
||||
return aUnit == eStyleUnit_None || aUnit == eStyleUnit_Coord;
|
||||
}
|
||||
static inline PRBool IsFixedOffset(nsStyleUnit aUnit) {
|
||||
return aUnit == eStyleUnit_Coord;
|
||||
}
|
||||
static inline PRBool IsFixedHeight(nsStyleUnit aUnit) {
|
||||
return aUnit == eStyleUnit_Coord;
|
||||
}
|
||||
|
||||
static inline PRBool IsFixedWidth(const nsStyleCoord& aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_Coord ||
|
||||
(aCoord.GetUnit() == eStyleUnit_Enumerated &&
|
||||
(aCoord.GetIntValue() == NS_STYLE_WIDTH_MAX_CONTENT ||
|
||||
aCoord.GetIntValue() == NS_STYLE_WIDTH_MIN_CONTENT));
|
||||
}
|
||||
|
||||
static inline PRBool IsFixedMaxWidth(const nsStyleCoord& aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_None ||
|
||||
IsFixedWidth(aCoord);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
|
@ -286,9 +266,9 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
|||
// then our frame width does not depend on the parent width.
|
||||
// Note that borders never depend on the parent width
|
||||
// XXX All of the enumerated values except -moz-available are ok too.
|
||||
if (!IsFixedWidth(pos->mWidth) ||
|
||||
!IsFixedWidth(pos->mMinWidth) ||
|
||||
!IsFixedMaxWidth(pos->mMaxWidth) ||
|
||||
if (pos->WidthDependsOnContainer() ||
|
||||
pos->MinWidthDependsOnContainer() ||
|
||||
pos->MaxWidthDependsOnContainer() ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetLeftUnit()) ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetRightUnit())) {
|
||||
return PR_TRUE;
|
||||
|
@ -325,12 +305,12 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
|||
// and height is a length or height and bottom are auto and top is not auto,
|
||||
// then our frame height does not depend on the parent height.
|
||||
// Note that borders never depend on the parent height
|
||||
if (!(IsFixedHeight(pos->mHeight.GetUnit()) ||
|
||||
(pos->mHeight.GetUnit() == eStyleUnit_Auto &&
|
||||
if ((pos->HeightDependsOnContainer() &&
|
||||
!(pos->mHeight.GetUnit() == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetBottomUnit() == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetTopUnit() != eStyleUnit_Auto)) ||
|
||||
!IsFixedHeight(pos->mMinHeight.GetUnit()) ||
|
||||
!IsFixedMaxSize(pos->mMaxHeight.GetUnit()) ||
|
||||
pos->MinHeightDependsOnContainer() ||
|
||||
pos->MaxHeightDependsOnContainer() ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetTopUnit()) ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetBottomUnit())) {
|
||||
return PR_TRUE;
|
||||
|
|
|
@ -3486,8 +3486,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
this, aFloatAvailableSpace.mHasFloats);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aFloatAvailableSpace.mRect.x + borderPadding.left;
|
||||
nscoord x = aFloatAvailableSpace.mRect.x;
|
||||
nscoord availWidth = aFloatAvailableSpace.mRect.width;
|
||||
nscoord availHeight;
|
||||
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
|
||||
|
@ -5557,11 +5556,9 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
|
|||
availWidth = aFloatAvailableSpace.width;
|
||||
}
|
||||
|
||||
// aState.mY is relative to the border-top, make it relative to the content-top
|
||||
nscoord contentYOffset = aState.mY - aState.BorderPadding().top;
|
||||
nscoord availHeight = NS_UNCONSTRAINEDSIZE == aState.mContentArea.height
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: NS_MAX(0, aState.mContentArea.height - contentYOffset);
|
||||
: NS_MAX(0, aState.mContentArea.YMost() - aState.mY);
|
||||
|
||||
#ifdef DISABLE_FLOAT_BREAKING_IN_COLUMNS
|
||||
if (availHeight != NS_UNCONSTRAINEDSIZE &&
|
||||
|
@ -5574,8 +5571,8 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
|
|||
}
|
||||
#endif
|
||||
|
||||
return nsRect(aState.BorderPadding().left,
|
||||
aState.BorderPadding().top,
|
||||
return nsRect(aState.mContentArea.x,
|
||||
aState.mContentArea.y,
|
||||
availWidth, availHeight);
|
||||
}
|
||||
|
||||
|
@ -6610,7 +6607,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||
// Reflow the bullet now
|
||||
nsSize availSize;
|
||||
// Make up a width since it doesn't really matter (XXX).
|
||||
availSize.width = rs.ComputedWidth();
|
||||
availSize.width = aState.mContentArea.width;
|
||||
availSize.height = NS_UNCONSTRAINEDSIZE;
|
||||
|
||||
// Get the reason right.
|
||||
|
@ -6644,26 +6641,22 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||
// the block's border, and the bullet frame's margin.
|
||||
nscoord x;
|
||||
if (rs.mStyleVisibility->mDirection == NS_STYLE_DIRECTION_LTR) {
|
||||
// Note: floatAvailSpace.x is relative to the content box and never
|
||||
// less than zero. Converting to frame coordinates and subtracting
|
||||
// the padding and border cancel each other out, and the NS_MAX()
|
||||
// with 0 (or with the left border+padding) is even implied in the
|
||||
// right place.
|
||||
x = floatAvailSpace.x - reflowState.mComputedMargin.right - aMetrics.width;
|
||||
// The floatAvailSpace.x gives us the content/float edge. Then we
|
||||
// subtract out the left border/padding and the bullet's width and
|
||||
// margin to offset the position.
|
||||
x = floatAvailSpace.x - rs.mComputedBorderPadding.left
|
||||
- reflowState.mComputedMargin.right - aMetrics.width;
|
||||
} else {
|
||||
// The XMost() of the available space and the computed width both
|
||||
// give us offsets from the left content edge. Then we add the left
|
||||
// border/padding to get into frame coordinates, and the right
|
||||
// border/padding and the bullet's margin to offset the position.
|
||||
x = NS_MIN(rs.ComputedWidth(), floatAvailSpace.XMost())
|
||||
+ rs.mComputedBorderPadding.LeftRight()
|
||||
// The XMost() of the available space give us offsets from the left
|
||||
// border edge. Then we add the right border/padding and the
|
||||
// bullet's margin to offset the position.
|
||||
x = floatAvailSpace.XMost() + rs.mComputedBorderPadding.right
|
||||
+ reflowState.mComputedMargin.left;
|
||||
}
|
||||
|
||||
// Approximate the bullets position; vertical alignment will provide
|
||||
// the final vertical location.
|
||||
const nsMargin& bp = aState.BorderPadding();
|
||||
nscoord y = bp.top;
|
||||
nscoord y = aState.mContentArea.y;
|
||||
mBullet->SetRect(nsRect(x, y, aMetrics.width, aMetrics.height));
|
||||
mBullet->DidReflow(aState.mPresContext, &aState.mReflowState, NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
|
|
|
@ -278,24 +278,11 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
|||
// from 10.3.3 to determine what to apply. At this point in the
|
||||
// reflow auto left/right margins will have a zero value.
|
||||
|
||||
nscoord x = mSpace.x + aFrameRS.mComputedMargin.left;
|
||||
nscoord y = mSpace.y + mTopMargin.get() + aClearance;
|
||||
mX = tx = mSpace.x + aFrameRS.mComputedMargin.left;
|
||||
mY = ty = mSpace.y + mTopMargin.get() + aClearance;
|
||||
|
||||
if ((mFrame->GetStateBits() & NS_BLOCK_FLOAT_MGR) == 0)
|
||||
aFrameRS.mBlockDelta = mOuterReflowState.mBlockDelta + y - aLine->mBounds.y;
|
||||
|
||||
mX = x;
|
||||
mY = y;
|
||||
|
||||
// Compute the translation to be used for adjusting the spacemanagager
|
||||
// coordinate system for the frame. The spacemanager coordinates are
|
||||
// <b>inside</b> the callers border+padding, but the x/y coordinates
|
||||
// are not (recall that frame coordinates are relative to the parents
|
||||
// origin and that the parents border/padding is <b>inside</b> the
|
||||
// parent frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
tx = x - mOuterReflowState.mComputedBorderPadding.left;
|
||||
ty = y - mOuterReflowState.mComputedBorderPadding.top;
|
||||
aFrameRS.mBlockDelta = mOuterReflowState.mBlockDelta + ty - aLine->mBounds.y;
|
||||
}
|
||||
|
||||
// Let frame know that we are reflowing it
|
||||
|
|
|
@ -102,9 +102,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||
NS_ASSERTION(mFloatManager,
|
||||
"FloatManager should be set in nsBlockReflowState" );
|
||||
if (mFloatManager) {
|
||||
// Translate into our content area and then save the
|
||||
// coordinate system origin for later.
|
||||
mFloatManager->Translate(borderPadding.left, borderPadding.top);
|
||||
// Save the coordinate system origin for later.
|
||||
mFloatManager->GetTranslation(mFloatManagerX, mFloatManagerY);
|
||||
mFloatManager->PushState(&mFloatManagerStateBefore); // never popped
|
||||
}
|
||||
|
@ -139,8 +137,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||
SetFlag(BRS_UNCONSTRAINEDHEIGHT, PR_TRUE);
|
||||
mContentArea.height = mBottomEdge = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
|
||||
mY = borderPadding.top;
|
||||
mContentArea.x = borderPadding.left;
|
||||
mY = mContentArea.y = borderPadding.top;
|
||||
|
||||
mPrevChild = nsnull;
|
||||
mCurrentLine = aFrame->end_lines();
|
||||
|
@ -148,16 +146,6 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||
mMinLineHeight = aReflowState.CalcLineHeight();
|
||||
}
|
||||
|
||||
nsBlockReflowState::~nsBlockReflowState()
|
||||
{
|
||||
// Restore the coordinate system, unless the float manager is null,
|
||||
// which means it was just destroyed.
|
||||
if (mFloatManager) {
|
||||
const nsMargin& borderPadding = BorderPadding();
|
||||
mFloatManager->Translate(-borderPadding.left, -borderPadding.top);
|
||||
}
|
||||
}
|
||||
|
||||
nsLineBox*
|
||||
nsBlockReflowState::NewLineBox(nsIFrame* aFrame,
|
||||
PRInt32 aCount,
|
||||
|
@ -187,9 +175,9 @@ nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
|
|||
// only give it free space. An example is a table frame - the
|
||||
// tables do not flow around floats.
|
||||
// However, we can let its margins intersect floats.
|
||||
NS_ASSERTION(aFloatAvailableSpace.x >= 0, "bad avail space rect x");
|
||||
NS_ASSERTION(aFloatAvailableSpace.x >= mContentArea.x, "bad avail space rect x");
|
||||
NS_ASSERTION(aFloatAvailableSpace.width == 0 ||
|
||||
aFloatAvailableSpace.XMost() <= mContentArea.width,
|
||||
aFloatAvailableSpace.XMost() <= mContentArea.XMost(),
|
||||
"bad avail space rect width");
|
||||
|
||||
nscoord leftOffset, rightOffset;
|
||||
|
@ -210,13 +198,13 @@ nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
|
|||
aReplacedWidth->marginRight == os.mComputedMargin.right),
|
||||
"unexpected aReplacedWidth");
|
||||
|
||||
nscoord leftFloatXOffset = aFloatAvailableSpace.x;
|
||||
nscoord leftFloatXOffset = aFloatAvailableSpace.x - mContentArea.x;
|
||||
leftOffset = NS_MAX(leftFloatXOffset, os.mComputedMargin.left) -
|
||||
(aReplacedWidth ? aReplacedWidth->marginLeft
|
||||
: os.mComputedMargin.left);
|
||||
leftOffset = NS_MAX(leftOffset, 0); // in case of negative margin
|
||||
nscoord rightFloatXOffset =
|
||||
mContentArea.width - aFloatAvailableSpace.XMost();
|
||||
mContentArea.XMost() - aFloatAvailableSpace.XMost();
|
||||
rightOffset = NS_MAX(rightFloatXOffset, os.mComputedMargin.right) -
|
||||
(aReplacedWidth ? aReplacedWidth->marginRight
|
||||
: os.mComputedMargin.right);
|
||||
|
@ -248,8 +236,6 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
// it off the page/column. Negative available height can confuse other code
|
||||
// and is nonsense in principle.
|
||||
|
||||
const nsMargin& borderPadding = BorderPadding();
|
||||
|
||||
// XXX Do we really want this condition to be this restrictive (i.e.,
|
||||
// more restrictive than it used to be)? The |else| here is allowed
|
||||
// by the CSS spec, but only out of desperation given implementations,
|
||||
|
@ -275,14 +261,14 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floats
|
||||
// The child block will flow around the float. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.x = mContentArea.x;
|
||||
aResult.width = mContentArea.width;
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_MARGIN:
|
||||
{
|
||||
// The child block's margins should be placed adjacent to,
|
||||
// but not overlap the float.
|
||||
aResult.x = aFloatAvailableSpace.mRect.x + borderPadding.left;
|
||||
aResult.x = aFloatAvailableSpace.mRect.x;
|
||||
aResult.width = aFloatAvailableSpace.mRect.width;
|
||||
}
|
||||
break;
|
||||
|
@ -292,7 +278,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
// Since there are no floats present the float-edge property
|
||||
// doesn't matter therefore give the block element all of the
|
||||
// available space since it will flow around the float itself.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.x = mContentArea.x;
|
||||
aResult.width = mContentArea.width;
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +296,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
|
||||
leftOffset, rightOffset,
|
||||
replacedWidth);
|
||||
aResult.x = borderPadding.left + leftOffset;
|
||||
aResult.x = mContentArea.x + leftOffset;
|
||||
aResult.width = mContentArea.width - leftOffset - rightOffset;
|
||||
}
|
||||
|
||||
|
@ -332,12 +318,11 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
|
|||
"bad coord system");
|
||||
#endif
|
||||
|
||||
nscoord y = aY - BorderPadding().top;
|
||||
nscoord height = (mContentArea.height == nscoord_MAX)
|
||||
? nscoord_MAX : NS_MAX(mContentArea.height - y, 0);
|
||||
? nscoord_MAX : NS_MAX(mContentArea.YMost() - aY, 0);
|
||||
nsFlowAreaRect result =
|
||||
mFloatManager->GetFlowArea(y, nsFloatManager::BAND_FROM_POINT,
|
||||
height, mContentArea.width, aState);
|
||||
mFloatManager->GetFlowArea(aY, nsFloatManager::BAND_FROM_POINT,
|
||||
height, mContentArea, aState);
|
||||
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.width < 0)
|
||||
result.mRect.width = 0;
|
||||
|
@ -367,9 +352,8 @@ nsBlockReflowState::GetFloatAvailableSpaceForHeight(
|
|||
#endif
|
||||
|
||||
nsFlowAreaRect result =
|
||||
mFloatManager->GetFlowArea(aY - BorderPadding().top,
|
||||
nsFloatManager::WIDTH_WITHIN_HEIGHT,
|
||||
aHeight, mContentArea.width, aState);
|
||||
mFloatManager->GetFlowArea(aY, nsFloatManager::WIDTH_WITHIN_HEIGHT,
|
||||
aHeight, mContentArea, aState);
|
||||
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.width < 0)
|
||||
result.mRect.width = 0;
|
||||
|
@ -510,12 +494,6 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
|
|||
|
||||
// Place floats for this line into the float manager
|
||||
if (aLine->HasFloats() || aLine->IsBlock()) {
|
||||
// Undo border/padding translation since the nsFloatCache's
|
||||
// coordinates are relative to the frame not relative to the
|
||||
// border/padding.
|
||||
const nsMargin& bp = BorderPadding();
|
||||
mFloatManager->Translate(-bp.left, -bp.top);
|
||||
|
||||
RecoverFloats(aLine, aDeltaY);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -523,8 +501,6 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
|
|||
mFloatManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mFloatManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,8 +576,7 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
|
|||
if (placed) {
|
||||
// Pass on updated available space to the current inline reflow engine
|
||||
nsFlowAreaRect floatAvailSpace = GetFloatAvailableSpace(mY);
|
||||
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x + BorderPadding().left,
|
||||
mY),
|
||||
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x, mY),
|
||||
floatAvailSpace.mRect.Size());
|
||||
aLineLayout->UpdateBand(availSpace, aFloat);
|
||||
// Record this float in the current-line list
|
||||
|
@ -681,7 +656,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
|
||||
// Enforce CSS2 9.5.1 rule [2], i.e., make sure that a float isn't
|
||||
// ``above'' another float that preceded it in the flow.
|
||||
mY = NS_MAX(mFloatManager->GetLowestFloatTop() + BorderPadding().top, mY);
|
||||
mY = NS_MAX(mFloatManager->GetLowestFloatTop(), mY);
|
||||
|
||||
// See if the float should clear any preceding floats...
|
||||
// XXX We need to mark this float somehow so that it gets reflowed
|
||||
|
@ -791,10 +766,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
// We don't worry about the geometry of the prev in flow, let the continuation
|
||||
// place and size itself as required.
|
||||
|
||||
// Assign an x and y coordinate to the float. Note that the x,y
|
||||
// coordinates are computed <b>relative to the translation in the
|
||||
// spacemanager</b> which means that the impacted region will be
|
||||
// <b>inside</b> the border/padding area.
|
||||
// Assign an x and y coordinate to the float.
|
||||
nscoord floatX, floatY;
|
||||
if (NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) {
|
||||
floatX = floatAvailableSpace.mRect.x;
|
||||
|
@ -810,16 +782,12 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
floatX = floatAvailableSpace.mRect.x;
|
||||
}
|
||||
}
|
||||
const nsMargin& borderPadding = BorderPadding();
|
||||
floatY = mY - borderPadding.top;
|
||||
if (floatY < 0) {
|
||||
// CSS2 spec, 9.5.1 rule [4]: "A floating box's outer top may not
|
||||
// be higher than the top of its containing block." (Since the
|
||||
// containing block is the content edge of the block box, this
|
||||
// means the margin edge of the float can't be higher than the
|
||||
// content edge of the block that contains it.)
|
||||
floatY = 0;
|
||||
}
|
||||
// CSS2 spec, 9.5.1 rule [4]: "A floating box's outer top may not
|
||||
// be higher than the top of its containing block." (Since the
|
||||
// containing block is the content edge of the block box, this
|
||||
// means the margin edge of the float can't be higher than the
|
||||
// content edge of the block that contains it.)
|
||||
floatY = NS_MAX(mY, mContentArea.y);
|
||||
|
||||
// Reflow the float after computing its vertical position so it knows
|
||||
// where to break.
|
||||
|
@ -845,7 +813,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
(!mReflowState.mFlags.mIsTopOfPage || !IsAdjacentWithTop() ||
|
||||
pushedDown) &&
|
||||
aFloat->GetSize().height + floatMargin.TopBottom() >
|
||||
mContentArea.height - floatY) ||
|
||||
mContentArea.YMost() - floatY) ||
|
||||
NS_FRAME_IS_TRUNCATED(reflowStatus)) {
|
||||
|
||||
PushFloatPastBreak(aFloat);
|
||||
|
@ -853,11 +821,10 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
}
|
||||
|
||||
// Calculate the actual origin of the float frame's border rect
|
||||
// relative to the parent block; floatX/Y must be converted from space-manager
|
||||
// coordinates to parent coordinates, and the margin must be added in
|
||||
// relative to the parent block; the margin must be added in
|
||||
// to get the border rect
|
||||
nsPoint origin(borderPadding.left + floatMargin.left + floatX,
|
||||
borderPadding.top + floatMargin.top + floatY);
|
||||
nsPoint origin(floatMargin.left + floatX,
|
||||
floatMargin.top + floatY);
|
||||
|
||||
// If float is relatively positioned, factor that in as well
|
||||
origin += aFloat->GetRelativeOffset(floatDisplay);
|
||||
|
@ -884,9 +851,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
region.height = NS_MAX(region.height, mContentArea.height - floatY);
|
||||
}
|
||||
nsresult rv =
|
||||
// spacemanager translation is inset by the border+padding.
|
||||
mFloatManager->AddFloat(aFloat,
|
||||
region - nsPoint(borderPadding.left, borderPadding.top));
|
||||
mFloatManager->AddFloat(aFloat, region);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "bad float placement");
|
||||
// store region
|
||||
rv = nsFloatManager::StoreRegionFor(aFloat, region);
|
||||
|
@ -899,8 +864,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
// less damage; e.g., if only height has changed, then only note the
|
||||
// area into which the float has grown or from which the float has
|
||||
// shrunk.
|
||||
nscoord top = NS_MIN(region.y, oldRegion.y) - borderPadding.top;
|
||||
nscoord bottom = NS_MAX(region.YMost(), oldRegion.YMost()) - borderPadding.top;
|
||||
nscoord top = NS_MIN(region.y, oldRegion.y);
|
||||
nscoord bottom = NS_MAX(region.YMost(), oldRegion.YMost());
|
||||
mFloatManager->IncludeInDamage(top, bottom);
|
||||
}
|
||||
|
||||
|
@ -993,8 +958,7 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType,
|
|||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("clear floats: in: aY=%d(%d)\n",
|
||||
aY, aY - BorderPadding().top);
|
||||
printf("clear floats: in: aY=%d\n", aY);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1004,12 +968,10 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType,
|
|||
mFloatManager->List(stdout);
|
||||
#endif
|
||||
|
||||
const nsMargin& bp = BorderPadding();
|
||||
nscoord newY = aY;
|
||||
|
||||
if (aBreakType != NS_STYLE_CLEAR_NONE) {
|
||||
newY = bp.top +
|
||||
mFloatManager->ClearFloats(newY - bp.top, aBreakType, aFlags);
|
||||
newY = mFloatManager->ClearFloats(newY, aBreakType, aFlags);
|
||||
}
|
||||
|
||||
if (aReplacedBlock) {
|
||||
|
@ -1019,11 +981,10 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType,
|
|||
nsBlockFrame::WidthToClearPastFloats(*this, floatAvailableSpace.mRect,
|
||||
aReplacedBlock);
|
||||
if (!floatAvailableSpace.mHasFloats ||
|
||||
NS_MAX(floatAvailableSpace.mRect.x, replacedWidth.marginLeft) +
|
||||
NS_MAX(floatAvailableSpace.mRect.x - mContentArea.x,
|
||||
replacedWidth.marginLeft) +
|
||||
replacedWidth.borderBoxWidth +
|
||||
NS_MAX(mContentArea.width -
|
||||
NS_MIN(mContentArea.width,
|
||||
floatAvailableSpace.mRect.XMost()),
|
||||
NS_MAX(mContentArea.XMost() - floatAvailableSpace.mRect.XMost(),
|
||||
replacedWidth.marginRight) <=
|
||||
mContentArea.width) {
|
||||
break;
|
||||
|
@ -1047,7 +1008,7 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType,
|
|||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("clear floats: out: y=%d(%d)\n", newY, newY - bp.top);
|
||||
printf("clear floats: out: y=%d\n", newY);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -75,8 +75,6 @@ public:
|
|||
PRBool aTopMarginRoot, PRBool aBottomMarginRoot,
|
||||
PRBool aBlockNeedsFloatManager);
|
||||
|
||||
~nsBlockReflowState();
|
||||
|
||||
/**
|
||||
* Get the available reflow space (the area not occupied by floats)
|
||||
* for the current y coordinate. The available space is relative to
|
||||
|
@ -220,12 +218,15 @@ public:
|
|||
|
||||
nscoord mBottomEdge;
|
||||
|
||||
// The content area to reflow child frames within. The x/y
|
||||
// coordinates are known to be mBorderPadding.left and
|
||||
// mBorderPadding.top. The width/height may be NS_UNCONSTRAINEDSIZE
|
||||
// if the container reflowing this frame has given the frame an
|
||||
// unconstrained area.
|
||||
nsSize mContentArea;
|
||||
// The content area to reflow child frames within. This is within
|
||||
// this frame's coordinate system, which means mContentArea.x ==
|
||||
// BorderPadding().left and mContentArea.y == BorderPadding().top.
|
||||
// The height may be NS_UNCONSTRAINEDSIZE, which indicates that there
|
||||
// is no page/column boundary below (the common case).
|
||||
// mContentArea.YMost() should only be called after checking that
|
||||
// mContentArea.height is not NS_UNCONSTRAINEDSIZE; otherwise
|
||||
// coordinate overflow may occur.
|
||||
nsRect mContentArea;
|
||||
|
||||
// Continuation out-of-flow float frames that need to move to our
|
||||
// next in flow are placed here during reflow. It's a pointer to
|
||||
|
|
|
@ -144,11 +144,11 @@ void nsFloatManager::Shutdown()
|
|||
|
||||
nsFlowAreaRect
|
||||
nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
|
||||
nscoord aHeight, nscoord aContentAreaWidth,
|
||||
nscoord aHeight, nsRect aContentArea,
|
||||
SavedState* aState) const
|
||||
{
|
||||
NS_ASSERTION(aHeight >= 0, "unexpected max height");
|
||||
NS_ASSERTION(aContentAreaWidth >= 0, "unexpected content area width");
|
||||
NS_ASSERTION(aContentArea.width >= 0, "unexpected content area width");
|
||||
|
||||
nscoord top = aYOffset + mY;
|
||||
if (top < nscoord_MIN) {
|
||||
|
@ -172,7 +172,8 @@ nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
|
|||
if (floatCount == 0 ||
|
||||
(mFloats[floatCount-1].mLeftYMost <= top &&
|
||||
mFloats[floatCount-1].mRightYMost <= top)) {
|
||||
return nsFlowAreaRect(0, aYOffset, aContentAreaWidth, aHeight, PR_FALSE);
|
||||
return nsFlowAreaRect(aContentArea.x, aYOffset, aContentArea.width,
|
||||
aHeight, PR_FALSE);
|
||||
}
|
||||
|
||||
nscoord bottom;
|
||||
|
@ -189,8 +190,8 @@ nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
|
|||
bottom = nscoord_MAX;
|
||||
}
|
||||
}
|
||||
nscoord left = mX;
|
||||
nscoord right = aContentAreaWidth + mX;
|
||||
nscoord left = mX + aContentArea.x;
|
||||
nscoord right = mX + aContentArea.XMost();
|
||||
if (right < left) {
|
||||
NS_WARNING("bad value");
|
||||
right = left;
|
||||
|
|
|
@ -156,14 +156,13 @@ public:
|
|||
* @param aY [in] vertical coordinate for top of available space
|
||||
* desired
|
||||
* @param aHeight [in] see above
|
||||
* @param aContentAreaWidth [in] the width of the content area (whose left
|
||||
* edge must be zero in the current translation)
|
||||
* @param aContentArea [in] an nsRect representing the content area
|
||||
* @param aState [in] If null, use the current state, otherwise, do
|
||||
* computation based only on floats present in the given
|
||||
* saved state.
|
||||
* @return An nsFlowAreaRect whose:
|
||||
* mRect is the resulting rectangle for line boxes. It will not go
|
||||
* left of 0, nor right of aContentAreaWidth, but will be
|
||||
* mRect is the resulting rectangle for line boxes. It will not
|
||||
* extend beyond aContentArea's horizontal bounds, but may be
|
||||
* narrower when floats are present.
|
||||
* mBandHasFloats is whether there are floats at the sides of the
|
||||
* return value including those that do not reduce the line box
|
||||
|
@ -173,7 +172,7 @@ public:
|
|||
*/
|
||||
enum BandInfoType { BAND_FROM_POINT, WIDTH_WITHIN_HEIGHT };
|
||||
nsFlowAreaRect GetFlowArea(nscoord aY, BandInfoType aInfoType,
|
||||
nscoord aHeight, nscoord aContentAreaWidth,
|
||||
nscoord aHeight, nsRect aContentArea,
|
||||
SavedState* aState) const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1157,29 +1157,6 @@ nsXULScrollFrame::GetMaxSize(nsBoxLayoutState& aState)
|
|||
return maxSize;
|
||||
}
|
||||
|
||||
#if 0 // XXXldb I don't think this is even needed
|
||||
/* virtual */ nscoord
|
||||
nsXULScrollFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
|
||||
{
|
||||
nsStyleUnit widthUnit = GetStylePosition()->mWidth.GetUnit();
|
||||
if (widthUnit == eStyleUnit_Percent || widthUnit == eStyleUnit_Auto) {
|
||||
nsMargin border = aReflowState.mComputedBorderPadding;
|
||||
aDesiredSize.mMaxElementWidth = border.right + border.left;
|
||||
mMaxElementWidth = aDesiredSize.mMaxElementWidth;
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("Use the info from the scrolled frame");
|
||||
#if 0
|
||||
// if not set then use the cached size. If set then set it.
|
||||
if (aDesiredSize.mMaxElementWidth == -1)
|
||||
aDesiredSize.mMaxElementWidth = mMaxElementWidth;
|
||||
else
|
||||
mMaxElementWidth = aDesiredSize.mMaxElementWidth;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsXULScrollFrame::GetFrameName(nsAString& aResult) const
|
||||
|
|
|
@ -125,13 +125,8 @@ static PRBool HaveFixedSize(const nsStylePosition* aStylePosition)
|
|||
// check the width and height values in the reflow state's style struct
|
||||
// - if width and height are specified as either coord or percentage, then
|
||||
// the size of the image frame is constrained
|
||||
nsStyleUnit widthUnit = aStylePosition->mWidth.GetUnit();
|
||||
nsStyleUnit heightUnit = aStylePosition->mHeight.GetUnit();
|
||||
|
||||
return ((widthUnit == eStyleUnit_Coord ||
|
||||
widthUnit == eStyleUnit_Percent) &&
|
||||
(heightUnit == eStyleUnit_Coord ||
|
||||
heightUnit == eStyleUnit_Percent));
|
||||
return aStylePosition->mWidth.IsCoordPercentCalcUnit() &&
|
||||
aStylePosition->mHeight.IsCoordPercentCalcUnit();
|
||||
}
|
||||
// use the data in the reflow state to decide if the image has a constrained size
|
||||
// (i.e. width and height that are based on the containing block size and not the image size)
|
||||
|
@ -146,11 +141,15 @@ inline PRBool HaveFixedSize(const nsHTMLReflowState& aReflowState)
|
|||
// during pass 1 reflow, ComputedWidth() is NS_UNCONSTRAINEDSIZE
|
||||
// in pass 2 reflow, ComputedWidth() is 0, it also needs to return PR_FALSE
|
||||
// see bug 156731
|
||||
nsStyleUnit heightUnit = (*(aReflowState.mStylePosition)).mHeight.GetUnit();
|
||||
nsStyleUnit widthUnit = (*(aReflowState.mStylePosition)).mWidth.GetUnit();
|
||||
return ((eStyleUnit_Percent == heightUnit && NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight()) ||
|
||||
(eStyleUnit_Percent == widthUnit && (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedWidth() ||
|
||||
0 == aReflowState.ComputedWidth())))
|
||||
const nsStyleCoord &height = aReflowState.mStylePosition->mHeight;
|
||||
const nsStyleCoord &width = aReflowState.mStylePosition->mWidth;
|
||||
return (((eStyleUnit_Percent == height.GetUnit() ||
|
||||
(height.IsCalcUnit() && height.CalcHasPercent())) &&
|
||||
NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight()) ||
|
||||
((eStyleUnit_Percent == width.GetUnit() ||
|
||||
(width.IsCalcUnit() && width.CalcHasPercent())) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aReflowState.ComputedWidth() ||
|
||||
0 == aReflowState.ComputedWidth())))
|
||||
? PR_FALSE
|
||||
: HaveFixedSize(aReflowState.mStylePosition);
|
||||
}
|
||||
|
|
|
@ -653,16 +653,6 @@ HasPercentageUnitSide(const nsStyleSides& aSides)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
WidthDependsOnContainer(const nsStyleCoord& aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_Percent ||
|
||||
(aCoord.GetUnit() == eStyleUnit_Enumerated &&
|
||||
(aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE ||
|
||||
aCoord.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT));
|
||||
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsPercentageAware(const nsIFrame* aFrame)
|
||||
{
|
||||
|
@ -694,9 +684,10 @@ IsPercentageAware(const nsIFrame* aFrame)
|
|||
|
||||
const nsStylePosition* pos = aFrame->GetStylePosition();
|
||||
|
||||
if (WidthDependsOnContainer(pos->mWidth) ||
|
||||
WidthDependsOnContainer(pos->mMaxWidth) ||
|
||||
WidthDependsOnContainer(pos->mMinWidth) ||
|
||||
if ((pos->WidthDependsOnContainer() &&
|
||||
pos->mWidth.GetUnit() != eStyleUnit_Auto) ||
|
||||
pos->MaxWidthDependsOnContainer() ||
|
||||
pos->MinWidthDependsOnContainer() ||
|
||||
eStyleUnit_Percent == pos->mOffset.GetRightUnit() ||
|
||||
eStyleUnit_Percent == pos->mOffset.GetLeftUnit()) {
|
||||
return PR_TRUE;
|
||||
|
@ -822,25 +813,16 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
|
|||
// Let frame know that are reflowing it. Note that we don't bother
|
||||
// positioning the frame yet, because we're probably going to end up
|
||||
// moving it when we do the vertical alignment
|
||||
nscoord x = pfd->mBounds.x;
|
||||
nscoord y = pfd->mBounds.y;
|
||||
|
||||
aFrame->WillReflow(mPresContext);
|
||||
|
||||
// Adjust spacemanager coordinate system for the frame. The
|
||||
// spacemanager coordinates are <b>inside</b> the current spans
|
||||
// border+padding, but the x/y coordinates are not (recall that
|
||||
// frame coordinates are relative to the parents origin and that the
|
||||
// parents border/padding is <b>inside</b> the parent
|
||||
// frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
// Adjust spacemanager coordinate system for the frame.
|
||||
nsHTMLReflowMetrics metrics;
|
||||
#ifdef DEBUG
|
||||
metrics.width = nscoord(0xdeadbeef);
|
||||
metrics.height = nscoord(0xdeadbeef);
|
||||
#endif
|
||||
nscoord tx = x - psd->mReflowState->mComputedBorderPadding.left;
|
||||
nscoord ty = y - psd->mReflowState->mComputedBorderPadding.top;
|
||||
nscoord tx = pfd->mBounds.x;
|
||||
nscoord ty = pfd->mBounds.y;
|
||||
mFloatManager->Translate(tx, ty);
|
||||
|
||||
nsIAtom* frameType = aFrame->GetType();
|
||||
|
|
|
@ -172,6 +172,7 @@ SpacerFrame::GetDesiredSize(nsHTMLReflowMetrics& aMetrics, nsSize aPercentBase)
|
|||
float factor = position->mWidth.GetPercentValue();
|
||||
aMetrics.width = NSToCoordRound(factor * aPercentBase.width);
|
||||
}
|
||||
// else treat enumerated values and calc() like 'auto'
|
||||
|
||||
// height
|
||||
unit = position->mHeight.GetUnit();
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
== width-block-1.html width-block-1-ref.html
|
||||
== width-block-intrinsic-1.html width-block-intrinsic-1-ref.html
|
||||
== width-table-auto-1.html width-table-auto-1-ref.html
|
||||
== width-table-fixed-1.html width-table-fixed-1-ref.html
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on blocks</title>
|
||||
<style>
|
||||
|
||||
body { width: 500px }
|
||||
p { background: green; color: white; margin: 1px 0; font-size: 10px }
|
||||
|
||||
</style>
|
||||
|
||||
<p style="width: 247px">50% - 3px</p>
|
||||
<p style="width: 247px">25% - 3px + 25%</p>
|
||||
<p style="width: 247px">25% - 3px + 12.5% * 2</p>
|
||||
<p style="width: 247px">25% - 3px + 12.5%*2</p>
|
||||
<p style="width: 247px">25% - 3px + 2*12.5%</p>
|
||||
<p style="width: 247px">25% - 3px + 2 * 12.5%</p>
|
||||
<p style="width: 125px">min(25%, 150px)</p>
|
||||
<p style="width: 100px">min(25%, 100px)</p>
|
||||
<p style="width: 150px">max(25%, 150px)</p>
|
||||
<p style="width: 125px">max(25%, 100px)</p>
|
||||
<p style="width: 150px">min(25%, 150px) + 5%</p>
|
||||
<p style="width: 125px">min(25%, 100px) + 5%</p>
|
||||
<p style="width: 175px">max(25%, 150px) + 5%</p>
|
||||
<p style="width: 150px">max(25%, 100px) + 5%</p>
|
||||
<p style="width: 105px">min(25%, 150px) - 2em</p>
|
||||
<p style="width: 80px">min(25%, 100px) - 2em</p>
|
||||
<p style="width: 130px">max(25%, 150px) - 2em</p>
|
||||
<p style="width: 105px">max(25%, 100px) - 2em</p>
|
||||
<p style="width: 250px">30% + 20%</p>
|
||||
<p style="width: 250px">30% + max(20%, 1px)</p>
|
||||
<p style="width: 250px">max(25%, 50%)</p>
|
||||
<p style="width: 125px">max(25%, 50%)</p>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on blocks</title>
|
||||
<style>
|
||||
|
||||
body { width: 500px }
|
||||
p { background: green; color: white; margin: 1px 0; font-size: 10px }
|
||||
|
||||
</style>
|
||||
|
||||
<p style="width: -moz-calc(50% - 3px)">50% - 3px</p>
|
||||
<p style="width: -moz-calc(25% - 3px + 25%)">25% - 3px + 25%</p>
|
||||
<p style="width: -moz-calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
|
||||
<p style="width: -moz-calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
|
||||
<p style="width: -moz-calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
|
||||
<p style="width: -moz-calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
|
||||
<p style="width: -moz-min(25%, 150px)">min(25%, 150px)</p>
|
||||
<p style="width: -moz-calc(min(25%, 100px))">min(25%, 100px)</p>
|
||||
<p style="width: -moz-calc(max(25%, 150px))">max(25%, 150px)</p>
|
||||
<p style="width: -moz-max(25%, 100px)">max(25%, 100px)</p>
|
||||
<p style="width: -moz-calc(min(25%, 150px) + 5%)">min(25%, 150px) + 5%</p>
|
||||
<p style="width: -moz-calc(min(25%, 100px) + 5%)">min(25%, 100px) + 5%</p>
|
||||
<p style="width: -moz-calc(max(25%, 150px) + 5%)">max(25%, 150px) + 5%</p>
|
||||
<p style="width: -moz-calc(max(25%, 100px) + 5%)">max(25%, 100px) + 5%</p>
|
||||
<p style="width: -moz-calc(min(25%, 150px) - 2em)">min(25%, 150px) - 2em</p>
|
||||
<p style="width: -moz-calc(min(25%, 100px) - 2em)">min(25%, 100px) - 2em</p>
|
||||
<p style="width: -moz-calc(max(25%, 150px) - 2em)">max(25%, 150px) - 2em</p>
|
||||
<p style="width: -moz-calc(max(25%, 100px) - 2em)">max(25%, 100px) - 2em</p>
|
||||
<p style="width: -moz-calc(30% + 20%)">30% + 20%</p>
|
||||
<p style="width: -moz-calc(30% + max(20%, 1px))">30% + max(20%, 1px)</p>
|
||||
<p style="width: -moz-calc(max(25%, 50%))">max(25%, 50%)</p>
|
||||
<p style="width: -moz-calc(min(25%, 50%))">max(25%, 50%)</p>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>intrinsic width of width: calc() on blocks</title>
|
||||
<style>
|
||||
|
||||
body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
|
||||
|
||||
</style>
|
||||
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 47px"></div>
|
||||
<div style="width: 47px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 50px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 50px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
||||
<div style="width: 200px"></div>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>intrinsic width of width: calc() on blocks</title>
|
||||
<style>
|
||||
|
||||
body { font-size: 10px }
|
||||
body > div { float: left; clear: left;
|
||||
margin: 0 0 1px 0; background: blue; color: white; height: 5px }
|
||||
body > div > div > div { width: 200px }
|
||||
|
||||
</style>
|
||||
|
||||
<div><div style="width: -moz-calc(50% - 3px)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(5em - 3px)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(max(5em, 0) - 3px)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(max(5em, 0%) - 3px)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(5em - min(3px, 0%))"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(5em - min(3px, 0))"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(5em - 0%)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(50%)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(50px)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(25% + 25%)"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(min(25%, 50%))"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(max(25%, 50%))"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(min(25%, 100px))"><div></div></div></div>
|
||||
<div><div style="width: -moz-calc(max(25%, 100px))"><div></div></div></div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on table-layout: auto tables</title>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on table-layout: auto tables</title>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(500px)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(50%)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(min(50%, 500px))">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(max(50%, 500px))">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(2 * 10% + 0.5 * 500px)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on table-layout: auto tables</title>
|
||||
<style>
|
||||
table { table-layout: fixed; width: 500px; border-spacing: 0 }
|
||||
</style>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>width: calc() on table-layout: auto tables</title>
|
||||
<style>
|
||||
table { table-layout: fixed; width: 500px; border-spacing: 0 }
|
||||
</style>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(500px)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(50%)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(min(50%, 500px))">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(max(50%, 500px))">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
||||
<table border>
|
||||
<tr>
|
||||
<td style="width: -moz-calc(2 * 10% + 0.5 * 500px)">x</td>
|
||||
<td style="width: 100px">y</td>
|
||||
</table>
|
|
@ -41,15 +41,18 @@ include bugs/reftest.list
|
|||
# canvas 2D
|
||||
include canvas/reftest.list
|
||||
|
||||
# css calc() tests
|
||||
include css-calc/reftest.list
|
||||
|
||||
# css character encoding tests
|
||||
include css-charset/reftest.list
|
||||
|
||||
# css default pseudo class tests
|
||||
include css-default/reftest.list
|
||||
|
||||
# css @import tests
|
||||
include css-import/reftest.list
|
||||
|
||||
# css character encoding tests
|
||||
include css-charset/reftest.list
|
||||
|
||||
# css gradients
|
||||
include css-gradients/reftest.list
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define CSSCalc_h_
|
||||
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsStyleCoord.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -152,6 +153,38 @@ ComputeCalc(const typename CalcOps::input_type& aValue, CalcOps &aOps)
|
|||
}
|
||||
}
|
||||
|
||||
#define CHECK_UNIT(u_) \
|
||||
PR_STATIC_ASSERT(int(eCSSUnit_##u_) + 14 == int(eStyleUnit_##u_)); \
|
||||
PR_STATIC_ASSERT(eCSSUnit_##u_ >= eCSSUnit_Calc); \
|
||||
PR_STATIC_ASSERT(eCSSUnit_##u_ <= eCSSUnit_Calc_Maximum);
|
||||
|
||||
CHECK_UNIT(Calc)
|
||||
CHECK_UNIT(Calc_Plus)
|
||||
CHECK_UNIT(Calc_Minus)
|
||||
CHECK_UNIT(Calc_Times_L)
|
||||
CHECK_UNIT(Calc_Times_R)
|
||||
CHECK_UNIT(Calc_Divided)
|
||||
CHECK_UNIT(Calc_Minimum)
|
||||
CHECK_UNIT(Calc_Maximum)
|
||||
|
||||
#undef CHECK_UNIT
|
||||
|
||||
inline nsStyleUnit
|
||||
ConvertCalcUnit(nsCSSUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eCSSUnit_Calc <= aUnit &&
|
||||
aUnit <= eCSSUnit_Calc_Maximum, "out of range");
|
||||
return nsStyleUnit(aUnit + 14);
|
||||
}
|
||||
|
||||
inline nsCSSUnit
|
||||
ConvertCalcUnit(nsStyleUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eStyleUnit_Calc <= aUnit &&
|
||||
aUnit <= eStyleUnit_Calc_Maximum, "out of range");
|
||||
return nsCSSUnit(aUnit - 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* The input unit operation for input_type being nsCSSValue.
|
||||
*/
|
||||
|
@ -167,6 +200,30 @@ struct CSSValueInputCalcOps
|
|||
|
||||
};
|
||||
|
||||
/**
|
||||
* The input unit operation for input_type being nsStyleCoord
|
||||
*/
|
||||
struct StyleCoordInputCalcOps
|
||||
{
|
||||
typedef nsStyleCoord input_type;
|
||||
typedef nsStyleCoord::Array input_array_type;
|
||||
|
||||
static nsCSSUnit GetUnit(const nsStyleCoord& aValue)
|
||||
{
|
||||
if (aValue.IsCalcUnit()) {
|
||||
return css::ConvertCalcUnit(aValue.GetUnit());
|
||||
}
|
||||
return eCSSUnit_Null;
|
||||
}
|
||||
|
||||
float ComputeNumber(const nsStyleCoord& aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "SpecifiedToComputedCalcOps should not "
|
||||
"leave numbers in structure");
|
||||
return 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Basic*CalcOps provide a partial implementation of the CalcOps
|
||||
* template parameter to ComputeCalc, for those callers whose merging
|
||||
|
@ -275,37 +332,6 @@ struct NumbersAlreadyNormalizedOps : public CSSValueInputCalcOps
|
|||
}
|
||||
};
|
||||
|
||||
#define CHECK_UNIT(u_) \
|
||||
PR_STATIC_ASSERT(int(eCSSUnit_Calc_##u_) + 14 == int(eStyleUnit_Calc_##u_));\
|
||||
PR_STATIC_ASSERT(eCSSUnit_Calc_##u_ >= eCSSUnit_Calc_Plus); \
|
||||
PR_STATIC_ASSERT(eCSSUnit_Calc_##u_ <= eCSSUnit_Calc_Maximum);
|
||||
|
||||
CHECK_UNIT(Plus)
|
||||
CHECK_UNIT(Minus)
|
||||
CHECK_UNIT(Times_L)
|
||||
CHECK_UNIT(Times_R)
|
||||
CHECK_UNIT(Divided)
|
||||
CHECK_UNIT(Minimum)
|
||||
CHECK_UNIT(Maximum)
|
||||
|
||||
#undef CHECK_UNIT
|
||||
|
||||
inline nsStyleUnit
|
||||
ConvertCalcUnit(nsCSSUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eCSSUnit_Calc_Plus <= aUnit &&
|
||||
aUnit <= eCSSUnit_Calc_Maximum, "out of range");
|
||||
return nsStyleUnit(aUnit + 14);
|
||||
}
|
||||
|
||||
inline nsCSSUnit
|
||||
ConvertCalcUnit(nsStyleUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eStyleUnit_Calc_Plus <= aUnit &&
|
||||
aUnit <= eStyleUnit_Calc_Maximum, "out of range");
|
||||
return nsCSSUnit(aUnit - 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* SerializeCalc appends the serialization of aValue to a string.
|
||||
*
|
||||
|
|
|
@ -512,7 +512,9 @@ protected:
|
|||
PRBool ParseTransition();
|
||||
PRBool ParseTransitionTimingFunction();
|
||||
PRBool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
|
||||
PRBool ParseTransitionTimingFunctionValueComponent(float& aComponent, char aStop);
|
||||
PRBool ParseTransitionTimingFunctionValueComponent(float& aComponent,
|
||||
char aStop,
|
||||
PRBool aCheckRange);
|
||||
PRBool AppendValueToList(nsCSSValueList**& aListTail,
|
||||
const nsCSSValue& aValue);
|
||||
|
||||
|
@ -1307,6 +1309,7 @@ CSSParserImpl::GetURLInParens(nsString& aURL)
|
|||
NS_ASSERTION(!mHavePushBack, "mustn't have pushback at this point");
|
||||
do {
|
||||
if (! mScanner.NextURL(mToken)) {
|
||||
// EOF
|
||||
return PR_FALSE;
|
||||
}
|
||||
} while (eCSSToken_WhiteSpace == mToken.mType);
|
||||
|
@ -3613,7 +3616,8 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
aValue.SetColorValue(NS_RGB(r,g,b));
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE; // already pushed back
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
else if (mToken.mIdent.LowerCaseEqualsLiteral("-moz-rgba") ||
|
||||
mToken.mIdent.LowerCaseEqualsLiteral("rgba")) {
|
||||
|
@ -3627,7 +3631,8 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
aValue.SetColorValue(NS_RGBA(r, g, b, a));
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE; // already pushed back
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
else if (mToken.mIdent.LowerCaseEqualsLiteral("hsl")) {
|
||||
// hsl ( hue , saturation , lightness )
|
||||
|
@ -3636,6 +3641,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
aValue.SetColorValue(rgba);
|
||||
return PR_TRUE;
|
||||
}
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
else if (mToken.mIdent.LowerCaseEqualsLiteral("-moz-hsla") ||
|
||||
|
@ -3650,6 +3656,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
NS_GET_B(rgba), a));
|
||||
return PR_TRUE;
|
||||
}
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
@ -4472,12 +4479,20 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
|
|||
if (((aVariantMask & VARIANT_ATTR) != 0) &&
|
||||
(eCSSToken_Function == tk->mType) &&
|
||||
tk->mIdent.LowerCaseEqualsLiteral("attr")) {
|
||||
return ParseAttr(aValue);
|
||||
if (!ParseAttr(aValue)) {
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (((aVariantMask & VARIANT_CUBIC_BEZIER) != 0) &&
|
||||
(eCSSToken_Function == tk->mType)) {
|
||||
if (tk->mIdent.LowerCaseEqualsLiteral("cubic-bezier")) {
|
||||
return ParseTransitionTimingFunctionValues(aValue);
|
||||
if (!ParseTransitionTimingFunctionValues(aValue)) {
|
||||
SkipUntil(')');
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
if ((aVariantMask & VARIANT_CALC) &&
|
||||
|
@ -5729,7 +5744,7 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
|||
case eCSSProperty_height:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHLP, nsnull);
|
||||
case eCSSProperty_width:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHKLP,
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHKLP | VARIANT_CALC,
|
||||
nsCSSProps::kWidthKTable);
|
||||
case eCSSProperty_force_broken_image_icon:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HI, nsnull);
|
||||
|
@ -8859,10 +8874,10 @@ CSSParserImpl::ParseTransitionTimingFunctionValues(nsCSSValue& aValue)
|
|||
}
|
||||
|
||||
float x1, x2, y1, y2;
|
||||
if (!ParseTransitionTimingFunctionValueComponent(x1, ',') ||
|
||||
!ParseTransitionTimingFunctionValueComponent(y1, ',') ||
|
||||
!ParseTransitionTimingFunctionValueComponent(x2, ',') ||
|
||||
!ParseTransitionTimingFunctionValueComponent(y2, ')')) {
|
||||
if (!ParseTransitionTimingFunctionValueComponent(x1, ',', PR_TRUE) ||
|
||||
!ParseTransitionTimingFunctionValueComponent(y1, ',', PR_FALSE) ||
|
||||
!ParseTransitionTimingFunctionValueComponent(x2, ',', PR_TRUE) ||
|
||||
!ParseTransitionTimingFunctionValueComponent(y2, ')', PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -8878,14 +8893,19 @@ CSSParserImpl::ParseTransitionTimingFunctionValues(nsCSSValue& aValue)
|
|||
|
||||
PRBool
|
||||
CSSParserImpl::ParseTransitionTimingFunctionValueComponent(float& aComponent,
|
||||
char aStop)
|
||||
char aStop,
|
||||
PRBool aCheckRange)
|
||||
{
|
||||
if (!GetToken(PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsCSSToken* tk = &mToken;
|
||||
if (tk->mType == eCSSToken_Number) {
|
||||
aComponent = tk->mNumber;
|
||||
float num = tk->mNumber;
|
||||
if (aCheckRange && (num < 0.0 || num > 1.0)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
aComponent = num;
|
||||
if (ExpectSymbol(aStop, PR_TRUE)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -510,21 +510,19 @@ SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, nsStyleCoord& aCoord,
|
|||
SpecifiedToComputedCalcOps ops(aStyleContext, aStyleContext->PresContext(),
|
||||
aCanStoreInRuleTree);
|
||||
aCoord = ComputeCalc(aValue, ops);
|
||||
if (!aCoord.IsCalcUnit()) {
|
||||
// Some callers distinguish between calc(50%) and 50%, or calc(50px)
|
||||
// and 50px.
|
||||
nsStyleCoord::Array *array =
|
||||
nsStyleCoord::Array::Create(aStyleContext, aCanStoreInRuleTree, 1);
|
||||
array->Item(0) = aCoord;
|
||||
aCoord.SetArrayValue(array, eStyleUnit_Calc);
|
||||
}
|
||||
}
|
||||
|
||||
struct ComputeComputedCalcCalcOps : public css::BasicCoordCalcOps
|
||||
struct ComputeComputedCalcCalcOps : public css::StyleCoordInputCalcOps,
|
||||
public css::BasicCoordCalcOps
|
||||
{
|
||||
typedef nsStyleCoord input_type;
|
||||
typedef nsStyleCoord::Array input_array_type;
|
||||
|
||||
static nsCSSUnit GetUnit(const nsStyleCoord& aValue)
|
||||
{
|
||||
if (aValue.IsCalcUnit()) {
|
||||
return css::ConvertCalcUnit(aValue.GetUnit());
|
||||
}
|
||||
return eCSSUnit_Null;
|
||||
}
|
||||
|
||||
const nscoord mPercentageBasis;
|
||||
|
||||
ComputeComputedCalcCalcOps(nscoord aPercentageBasis)
|
||||
|
@ -543,13 +541,6 @@ struct ComputeComputedCalcCalcOps : public css::BasicCoordCalcOps
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float ComputeNumber(const nsStyleCoord& aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "SpecifiedToComputedCalcOps should not "
|
||||
"leave numbers in structure");
|
||||
return 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
// This is our public API for handling calc() expressions that involve
|
||||
|
@ -562,22 +553,6 @@ nsRuleNode::ComputeComputedCalc(const nsStyleCoord& aValue,
|
|||
return css::ComputeCalc(aValue, ops);
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsRuleNode::ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
|
||||
nscoord aPercentageBasis)
|
||||
{
|
||||
switch (aCoord.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
return aCoord.GetCoordValue();
|
||||
case eStyleUnit_Percent:
|
||||
return NSCoordSaturatingMultiply(aPercentageBasis,
|
||||
aCoord.GetPercentValue());
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(), "unexpected unit");
|
||||
return nsRuleNode::ComputeComputedCalc(aCoord, aPercentageBasis);
|
||||
}
|
||||
}
|
||||
|
||||
#define SETCOORD_NORMAL 0x01 // N
|
||||
#define SETCOORD_AUTO 0x02 // A
|
||||
#define SETCOORD_INHERIT 0x04 // H
|
||||
|
@ -5556,8 +5531,8 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
|
|||
}
|
||||
|
||||
SetCoord(posData.mWidth, pos->mWidth, parentPos->mWidth,
|
||||
SETCOORD_LPAEH | SETCOORD_INITIAL_AUTO, aContext,
|
||||
mPresContext, canStoreInRuleTree);
|
||||
SETCOORD_LPAEH | SETCOORD_INITIAL_AUTO | SETCOORD_STORE_CALC,
|
||||
aContext, mPresContext, canStoreInRuleTree);
|
||||
SetCoord(posData.mMinWidth, pos->mMinWidth, parentPos->mMinWidth,
|
||||
SETCOORD_LPEH | SETCOORD_INITIAL_ZERO, aContext,
|
||||
mPresContext, canStoreInRuleTree);
|
||||
|
|
|
@ -767,7 +767,11 @@ public:
|
|||
// Compute the value of an nsStyleCoord that is either a coord, a
|
||||
// percent, or a calc expression.
|
||||
static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
|
||||
nscoord aPercentageBasis);
|
||||
nscoord aPercentageBasis)
|
||||
{
|
||||
// ComputeComputedCalc will handle coords and percents correctly
|
||||
return ComputeComputedCalc(aCoord, aPercentageBasis);
|
||||
}
|
||||
|
||||
// Return whether the rule tree for which this node is the root has
|
||||
// cached data such that we need to do dynamic change handling for
|
||||
|
|
|
@ -128,7 +128,6 @@ public:
|
|||
const Value& aEndValue,
|
||||
double aPortion,
|
||||
Value& aResultValue) {
|
||||
NS_ABORT_IF_FALSE(0.0 <= aPortion && aPortion <= 1.0, "out of range");
|
||||
return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
|
||||
aPortion, aEndValue, aResultValue);
|
||||
}
|
||||
|
|
|
@ -211,6 +211,24 @@ nsStyleCoord::GetAngleValueInRadians() const
|
|||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStyleCoord::CalcHasPercent() const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(IsCalcUnit(), "caller should check IsCalcUnit()");
|
||||
nsStyleCoord::Array *a = GetArrayValue();
|
||||
for (size_t i = 0, i_end = a->Count(); i < i_end; ++i) {
|
||||
const nsStyleCoord &v = a->Item(i);
|
||||
if (v.GetUnit() == eStyleUnit_Percent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (v.IsCalcUnit() && v.CalcHasPercent()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
inline void*
|
||||
nsStyleCoord::Array::operator new(size_t aSelfSize,
|
||||
nsStyleContext *aAllocationContext,
|
||||
|
|
|
@ -60,12 +60,12 @@ enum nsStyleUnit {
|
|||
eStyleUnit_Coord = 20, // (nscoord) value is twips
|
||||
eStyleUnit_Integer = 30, // (int) value is simple integer
|
||||
eStyleUnit_Enumerated = 32, // (int) value has enumerated meaning
|
||||
// The following are all of the eCSSUnit_Calc_* types (but not
|
||||
// eCSSUnit_Calc itself, since we don't need to distinguish
|
||||
// calc(min()) from min() in compute dstyle). They are all weak
|
||||
// The following are all of the eCSSUnit_Calc_* types. They are weak
|
||||
// pointers to a calc tree allocated by nsStyleContext::Alloc.
|
||||
// NOTE: They are in the same order as the eCSSUnit_Calc_* values so
|
||||
// that converting between the two sets is just addition/subtraction.
|
||||
eStyleUnit_Calc = 39, // (Array*) calc() toplevel, to
|
||||
// distinguish 50% from calc(50%), etc.
|
||||
eStyleUnit_Calc_Plus = 40, // (Array*) + node within calc()
|
||||
eStyleUnit_Calc_Minus = 41, // (Array*) - within calc
|
||||
eStyleUnit_Calc_Times_L = 42, // (Array*) num * val within calc
|
||||
|
@ -121,9 +121,19 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsCalcUnit() const {
|
||||
return eStyleUnit_Calc_Plus <= mUnit && mUnit <= eStyleUnit_Calc_Maximum;
|
||||
return eStyleUnit_Calc <= mUnit && mUnit <= eStyleUnit_Calc_Maximum;
|
||||
}
|
||||
|
||||
PRBool IsCoordPercentCalcUnit() const {
|
||||
return mUnit == eStyleUnit_Coord ||
|
||||
mUnit == eStyleUnit_Percent ||
|
||||
IsCalcUnit();
|
||||
}
|
||||
|
||||
// Does this calc() expression have any percentages inside it? Can be
|
||||
// called only when IsCalcUnit() is true.
|
||||
PRBool CalcHasPercent() const;
|
||||
|
||||
PRBool IsArrayValue() const {
|
||||
return IsCalcUnit();
|
||||
}
|
||||
|
|
|
@ -1146,6 +1146,17 @@ nsChangeHint nsStylePosition::MaxDifference()
|
|||
}
|
||||
#endif
|
||||
|
||||
/* static */ PRBool
|
||||
nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_Auto ||
|
||||
aCoord.GetUnit() == eStyleUnit_Percent ||
|
||||
(aCoord.IsCalcUnit() && aCoord.CalcHasPercent()) ||
|
||||
(aCoord.GetUnit() == eStyleUnit_Enumerated &&
|
||||
(aCoord.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT ||
|
||||
aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE));
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// nsStyleTable
|
||||
//
|
||||
|
|
|
@ -1052,14 +1052,35 @@ struct nsStylePosition {
|
|||
static PRBool ForceCompare() { return PR_TRUE; }
|
||||
|
||||
nsStyleSides mOffset; // [reset] coord, percent, auto
|
||||
nsStyleCoord mWidth; // [reset] coord, percent, auto, enum
|
||||
nsStyleCoord mWidth; // [reset] coord, percent, enum, auto
|
||||
nsStyleCoord mMinWidth; // [reset] coord, percent, enum
|
||||
nsStyleCoord mMaxWidth; // [reset] coord, percent, null, enum
|
||||
nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, none
|
||||
nsStyleCoord mHeight; // [reset] coord, percent, auto
|
||||
nsStyleCoord mMinHeight; // [reset] coord, percent
|
||||
nsStyleCoord mMaxHeight; // [reset] coord, percent, null
|
||||
nsStyleCoord mMaxHeight; // [reset] coord, percent, none
|
||||
PRUint8 mBoxSizing; // [reset] see nsStyleConsts.h
|
||||
nsStyleCoord mZIndex; // [reset] integer, auto
|
||||
|
||||
PRBool WidthDependsOnContainer() const
|
||||
{ return WidthCoordDependsOnContainer(mWidth); }
|
||||
PRBool MinWidthDependsOnContainer() const
|
||||
{ return WidthCoordDependsOnContainer(mMinWidth); }
|
||||
PRBool MaxWidthDependsOnContainer() const
|
||||
{ return WidthCoordDependsOnContainer(mMaxWidth); }
|
||||
PRBool HeightDependsOnContainer() const
|
||||
{ return HeightCoordDependsOnContainer(mHeight); }
|
||||
PRBool MinHeightDependsOnContainer() const
|
||||
{ return HeightCoordDependsOnContainer(mMinHeight); }
|
||||
PRBool MaxHeightDependsOnContainer() const
|
||||
{ return HeightCoordDependsOnContainer(mMaxHeight); }
|
||||
|
||||
private:
|
||||
static PRBool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
|
||||
static PRBool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
|
||||
aCoord.GetUnit() == eStyleUnit_Percent;
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStyleTextReset {
|
||||
|
|
|
@ -175,6 +175,7 @@ _TEST_FILES = test_acid3_test46.html \
|
|||
test_transitions_per_property.html \
|
||||
test_transitions_dynamic_changes.html \
|
||||
test_transitions_bug537151.html \
|
||||
test_unclosed_parentheses.html \
|
||||
test_units_angle.html \
|
||||
test_units_frequency.html \
|
||||
test_units_length.html \
|
||||
|
|
|
@ -1031,7 +1031,10 @@ var gCSSProperties = {
|
|||
"-moz-repeating-radial-gradient(top left 99deg, cover, red, blue)",
|
||||
"-moz-repeating-radial-gradient(15% 20% -1.2345rad, circle, red, blue)",
|
||||
"-moz-repeating-radial-gradient(45px 399grad, ellipse closest-corner, red, blue)",
|
||||
"-moz-repeating-radial-gradient(45px 399grad, farthest-side circle, red, blue)"
|
||||
"-moz-repeating-radial-gradient(45px 399grad, farthest-side circle, red, blue)",
|
||||
"-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 2, 10, 10, 2)",
|
||||
"-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 10%, 50%, 30%, 0%)",
|
||||
"-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 10, 50%, 30%, 0)",
|
||||
],
|
||||
invalid_values: [
|
||||
/* Old syntax */
|
||||
|
@ -2138,8 +2141,8 @@ var gCSSProperties = {
|
|||
domProp: "textShadow",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "none" ],
|
||||
prerequisites: { "color": "blue" },
|
||||
initial_values: [ "none" ],
|
||||
other_values: [ "2px 2px", "2px 2px 1px", "2px 2px green", "2px 2px 1px green", "green 2px 2px", "green 2px 2px 1px", "green 2px 2px, blue 1px 3px 4px", "currentColor 3px 3px", "blue 2px 2px, currentColor 1px 2px",
|
||||
/* calc() values */
|
||||
"2px 2px -moz-calc(-5px)", /* clamped */
|
||||
|
@ -2211,8 +2214,8 @@ var gCSSProperties = {
|
|||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "ease", "cubic-bezier(0.25, 0.1, 0.25, 1.0)" ],
|
||||
other_values: [ "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)" ],
|
||||
invalid_values: [ "none", "auto" ]
|
||||
other_values: [ "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)" ],
|
||||
invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)" ]
|
||||
},
|
||||
"unicode-bidi": {
|
||||
domProp: "unicodeBidi",
|
||||
|
@ -2278,10 +2281,67 @@ var gCSSProperties = {
|
|||
domProp: "width",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
/* computed value tests for width test more with display:block */
|
||||
prerequisites: { "display": "block" },
|
||||
initial_values: [ " auto" ],
|
||||
/* XXX these have prerequisites */
|
||||
other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ],
|
||||
invalid_values: [ "none", "-2px" ]
|
||||
other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available",
|
||||
/* valid calc() values */
|
||||
"-moz-calc(-2px)",
|
||||
"-moz-calc(2px)",
|
||||
"-moz-calc(50%)",
|
||||
"-moz-calc(50% + 2px)",
|
||||
"-moz-calc( 50% + 2px)",
|
||||
"-moz-calc(50% + 2px )",
|
||||
"-moz-calc( 50% + 2px )",
|
||||
"-moz-calc(50% - -2px)",
|
||||
"-moz-calc(2px - -50%)",
|
||||
"-moz-calc(3*25px)",
|
||||
"-moz-calc(3 *25px)",
|
||||
"-moz-calc(3 * 25px)",
|
||||
"-moz-calc(3* 25px)",
|
||||
"-moz-calc(25px*3)",
|
||||
"-moz-calc(25px *3)",
|
||||
"-moz-calc(25px* 3)",
|
||||
"-moz-calc(25px * 3)",
|
||||
"-moz-calc(3*25px + 50%)",
|
||||
"-moz-calc(50% - 3em + 2px)",
|
||||
"-moz-calc(50% - (3em + 2px))",
|
||||
"-moz-calc((50% - 3em) + 2px)",
|
||||
"-moz-min(50%, 30em)",
|
||||
"-moz-calc(min(50%, 30em))",
|
||||
"-moz-max(30em, 2px + 50%)",
|
||||
"-moz-calc(max(30em, 2px + 50%))",
|
||||
"-moz-min(30%, 30em,200px, min(500px ,40em))",
|
||||
"-moz-calc(min(30%, 30em,200px, min(500px ,40em)))",
|
||||
"-moz-min(50%)",
|
||||
"-moz-max(20px)",
|
||||
"-moz-calc(min(2em))",
|
||||
"-moz-calc(max(50%))",
|
||||
"-moz-calc(50px/2)",
|
||||
"-moz-calc(50px/(2 - 1))"
|
||||
],
|
||||
invalid_values: [ "none", "-2px",
|
||||
/* invalid calc() values */
|
||||
"-moz-calc(50%+ 2px)",
|
||||
"-moz-calc(50% +2px)",
|
||||
"-moz-calc(50%+2px)",
|
||||
"-moz-min()",
|
||||
"-moz-calc(min())",
|
||||
"-moz-max()",
|
||||
"-moz-calc(max())",
|
||||
"-moz-calc(50px/(2 - 2))",
|
||||
/* If we ever support division by values, which is
|
||||
* complicated for the reasons described in
|
||||
* http://lists.w3.org/Archives/Public/www-style/2010Jan/0007.html
|
||||
* , we should support all 4 of these as described in
|
||||
* http://lists.w3.org/Archives/Public/www-style/2009Dec/0296.html
|
||||
*/
|
||||
"-moz-calc((3em / 100%) * 3em)",
|
||||
"-moz-calc(3em / 100% * 3em)",
|
||||
"-moz-calc(3em * (3em / 100%))",
|
||||
"-moz-calc(3em * 3em / 100%)"
|
||||
]
|
||||
},
|
||||
"word-spacing": {
|
||||
domProp: "wordSpacing",
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="property_database.js"></script>
|
||||
<style type="text/css" id="stylesheet"></style>
|
||||
<style type="text/css">
|
||||
/* For 'width', 'height', etc., need a constant size container. */
|
||||
#display { width: 500px; height: 200px }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -58,6 +62,9 @@ function setup_initial_values(id, ivalprop, prereqprop) {
|
|||
window[ivalprop] = iframe.contentWindow.getComputedStyle(
|
||||
iframe.contentDocument.documentElement.firstChild, "");
|
||||
var sheet = iframe.contentDocument.styleSheets[0];
|
||||
// For 'width', 'height', etc., need a constant size container.
|
||||
sheet.insertRule(":root { height: 200px; width: 500px }", sheet.cssRules.length);
|
||||
|
||||
window[prereqprop] = sheet.cssRules[sheet.insertRule(":root > * {}", sheet.cssRules.length)];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=575672
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 575672</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<style type="text/css" id="style"></style>
|
||||
<style type="text/css">
|
||||
#display { position: relative }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=575672">Mozilla Bug 575672</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for unclosed parentheses in CSS values. **/
|
||||
|
||||
// Each of the following declarations should have a single missing ')'
|
||||
// in the value.
|
||||
var declarations = [
|
||||
"content: url(",
|
||||
"content: url( ",
|
||||
"content: url(http://www.foo.com",
|
||||
"content: url('http://www.foo.com'",
|
||||
"background-image: -moz-linear-gradient(",
|
||||
"background-image: -moz-linear-gradient( ",
|
||||
"background-image: -moz-linear-gradient(red, blue",
|
||||
"background-image: -moz-linear-gradient(red, yellow, blue",
|
||||
"background-image: -moz-linear-gradient(red 1px, yellow 5px, blue 10px",
|
||||
"background-image: -moz-linear-gradient(red, yellow, rgb(0, 0, 255)",
|
||||
"background-image: -moz-repeating-linear-gradient(top left, red, blue",
|
||||
"background-image: -moz-linear-gradient(top left, red, yellow, blue",
|
||||
"background-image: -moz-linear-gradient(top left, red 1px, yellow 5px, blue 10px",
|
||||
"background-image: -moz-linear-gradient(top left, red, yellow, rgb(0, 0, 255)",
|
||||
"background-image: -moz-radial-gradient(",
|
||||
"background-image: -moz-radial-gradient( ",
|
||||
"background-image: -moz-radial-gradient(top left 45deg, red, blue",
|
||||
"background-image: -moz-radial-gradient(cover, red, blue",
|
||||
"background-image: -moz-repeating-radial-gradient(circle, red, blue",
|
||||
"background-image: -moz-radial-gradient(ellipse closest-corner, red, hsl(240, 50%, 50%)",
|
||||
"background-image: -moz-radial-gradient(farthest-side circle, red, blue",
|
||||
"background-image: -moz-image-rect(",
|
||||
"background-image: -moz-image-rect( ",
|
||||
"background-image: -moz-image-rect(url(foo.jpg)",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10 ",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10,",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, ",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, 10",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, 10 ",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, 10,",
|
||||
"background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, 10, ",
|
||||
"color: rgb(",
|
||||
"color: rgb( ",
|
||||
"color: rgb(128, 0",
|
||||
"color: rgb(128, 0, 128",
|
||||
"color: rgb(128, 0, 128, 128",
|
||||
"color: rgba(",
|
||||
"color: rgba( ",
|
||||
"color: rgba(128, 0",
|
||||
"color: rgba(128, 0, 128",
|
||||
"color: rgba(128, 0, 128, 1",
|
||||
"color: rgba(128, 0, 128, 1, 1",
|
||||
"color: hsl(",
|
||||
"color: hsl( ",
|
||||
"color: hsl(240, 50%",
|
||||
"color: hsl(240, 50%, 50%",
|
||||
"color: hsl(240, 50%, 50%, 50%",
|
||||
"color: hsla(",
|
||||
"color: hsla( ",
|
||||
"color: hsla(240, 50%",
|
||||
"color: hsla(240, 50%, 50%",
|
||||
"color: hsla(240, 50%, 50%, 1",
|
||||
"color: hsla(240, 50%, 50%, 1, 1",
|
||||
"content: counter(",
|
||||
"content: counter( ",
|
||||
"content: counter(foo",
|
||||
"content: counter(foo ",
|
||||
"content: counter(foo,",
|
||||
"content: counter(foo, ",
|
||||
"content: counter(foo, upper-roman",
|
||||
"content: counter(foo, upper-roman ",
|
||||
"content: counter(foo, upper-roman,",
|
||||
"content: counter(foo, upper-roman, ",
|
||||
"content: counters(",
|
||||
"content: counters( ",
|
||||
"content: counters(foo, ','",
|
||||
"content: counters(foo, ',' ",
|
||||
"content: counters(foo, ',',",
|
||||
"content: counters(foo, ',', ",
|
||||
"content: counters(foo, ',', upper-roman",
|
||||
"content: counters(foo, ',', upper-roman ",
|
||||
"content: counters(foo, ',', upper-roman,",
|
||||
"content: counters(foo, ',', upper-roman, ",
|
||||
"content: attr(",
|
||||
"content: attr( ",
|
||||
"content: attr(href",
|
||||
"content: attr(href ",
|
||||
"content: attr(html",
|
||||
"content: attr(html ",
|
||||
"content: attr(html|",
|
||||
"content: attr(html| ",
|
||||
"content: attr(html|href",
|
||||
"content: attr(html|href ",
|
||||
"content: attr(|",
|
||||
"content: attr(| ",
|
||||
"content: attr(|href",
|
||||
"content: attr(|href ",
|
||||
"-moz-transition-timing-function: cubic-bezier(",
|
||||
"-moz-transition-timing-function: cubic-bezier( ",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1 ",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1,",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1, ",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1, 1",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1, 1 ",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1, 1,",
|
||||
"-moz-transition-timing-function: cubic-bezier(0, 0, 1, 1, ",
|
||||
"border-top-width: -moz-calc(",
|
||||
"border-top-width: -moz-calc( ",
|
||||
"border-top-width: -moz-calc(2em",
|
||||
"border-top-width: -moz-calc(2em ",
|
||||
"border-top-width: -moz-calc(2em +",
|
||||
"border-top-width: -moz-calc(2em + ",
|
||||
"border-top-width: -moz-calc(2em *",
|
||||
"border-top-width: -moz-calc(2em * ",
|
||||
"border-top-width: -moz-calc((2em)",
|
||||
"border-top-width: -moz-calc((2em) ",
|
||||
];
|
||||
|
||||
var textNode = document.createTextNode("");
|
||||
document.getElementById("style").appendChild(textNode);
|
||||
var cs = getComputedStyle(document.getElementById("display"), "");
|
||||
|
||||
for (var i = 0; i < declarations.length; ++i) {
|
||||
var sheet = "@namespace html url(http://www.w3.org/1999/xhtml);\n" +
|
||||
"#display { color: green; " + declarations[i] +
|
||||
" x x x x x x x ; color: red; ) ; z-index: " + (i + 1) + " }";
|
||||
textNode.data = sheet;
|
||||
is(cs.color, "rgb(0, 128, 0)",
|
||||
"color for declaration '" + declarations[i] + "'");
|
||||
is(cs.zIndex, i+1,
|
||||
"z-index for declaration '" + declarations[i] + "'");
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -8,6 +8,10 @@
|
|||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="property_database.js"></script>
|
||||
<style type="text/css" id="stylesheet"></style>
|
||||
<style type="text/css">
|
||||
/* For 'width', 'height', etc., need a constant size container. */
|
||||
#display { width: 500px; height: 200px }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -79,6 +83,17 @@ function xfail_value(property, value, is_initial, has_frame) {
|
|||
return false;
|
||||
}
|
||||
|
||||
var gSwapInitialWhenHaveFrame = {
|
||||
// When there's a frame, '-moz-available' works out to the same as
|
||||
// 'auto' given the prerequisites of only 'display: block'.
|
||||
"width": [ "-moz-available" ],
|
||||
};
|
||||
|
||||
function swap_when_frame(property, value) {
|
||||
return (property in gSwapInitialWhenHaveFrame) &&
|
||||
gSwapInitialWhenHaveFrame[property].indexOf(value) != -1;
|
||||
}
|
||||
|
||||
var gElementN = document.getElementById("elementn");
|
||||
var gElementF = document.getElementById("elementf");
|
||||
var gStyleSheet = document.getElementById("stylesheet").sheet;
|
||||
|
@ -95,6 +110,9 @@ function setup_initial_values(id, ivalprop, prereqprop) {
|
|||
window[ivalprop] = iframe.contentWindow.getComputedStyle(
|
||||
iframe.contentDocument.documentElement.firstChild, "");
|
||||
var sheet = iframe.contentDocument.styleSheets[0];
|
||||
// For 'width', 'height', etc., need a constant size container.
|
||||
sheet.insertRule(":root { height: 200px; width: 500px }", sheet.cssRules.length);
|
||||
|
||||
window[prereqprop] = sheet.cssRules[sheet.insertRule(":root > * {}", sheet.cssRules.length)];
|
||||
}
|
||||
|
||||
|
@ -157,9 +175,11 @@ function test_value(property, val, is_initial)
|
|||
(xfail_value(property, val, is_initial, false) ? todo_isnot : isnot)(
|
||||
val_computed_n, initial_computed_n,
|
||||
"should not get initial value for '" + property + ":" + val + "' on elementn.");
|
||||
(xfail_value(property, val, is_initial, true) ? todo_isnot : isnot)(
|
||||
var swap = swap_when_frame(property, val);
|
||||
(xfail_value(property, val, is_initial, true) ? todo_isnot : (swap ? is : isnot))(
|
||||
val_computed_f, initial_computed_f,
|
||||
"should not get initial value for '" + property + ":" + val + "' on elementf.");
|
||||
"should " + (swap ? "" : "not ") +
|
||||
"get initial value for '" + property + ":" + val + "' on elementf.");
|
||||
}
|
||||
if (is_initial)
|
||||
gRule1.style.removeProperty(property);
|
||||
|
|
|
@ -470,13 +470,16 @@ static inline PRBool
|
|||
DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame)
|
||||
{
|
||||
const nsStylePosition *pos = aEmbeddingFrame->GetStylePosition();
|
||||
nsStyleUnit widthUnit = pos->mWidth.GetUnit();
|
||||
nsStyleUnit heightUnit = pos->mHeight.GetUnit();
|
||||
const nsStyleCoord &width = pos->mWidth;
|
||||
const nsStyleCoord &height = pos->mHeight;
|
||||
|
||||
// XXX it would be nice to know if the size of aEmbeddingFrame's containing
|
||||
// block depends on aEmbeddingFrame, then we'd know if we can return false
|
||||
// for eStyleUnit_Percent too.
|
||||
return (widthUnit != eStyleUnit_Coord) || (heightUnit != eStyleUnit_Coord);
|
||||
return (width.GetUnit() != eStyleUnit_Coord &&
|
||||
(!width.IsCalcUnit() || width.CalcHasPercent())) ||
|
||||
(height.GetUnit() != eStyleUnit_Coord &&
|
||||
(!height.IsCalcUnit() || height.CalcHasPercent()));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "SpanningCellSorter.h"
|
||||
|
||||
namespace css = mozilla::css;
|
||||
|
||||
#undef DEBUG_TABLE_STRATEGY
|
||||
|
||||
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aTableFrame)
|
||||
|
@ -120,11 +122,15 @@ GetWidthInfo(nsIRenderingContext *aRenderingContext,
|
|||
// XXXldb Should we consider -moz-box-sizing?
|
||||
|
||||
const nsStylePosition *stylePos = aFrame->GetStylePosition();
|
||||
nsStyleUnit unit = stylePos->mWidth.GetUnit();
|
||||
const nsStyleCoord &width = stylePos->mWidth;
|
||||
nsStyleUnit unit = width.GetUnit();
|
||||
// NOTE: We're ignoring calc() units here, for lack of a sensible
|
||||
// idea for what to do with them. This means calc() is basically
|
||||
// handled like 'auto' for table cells and columns.
|
||||
if (unit == eStyleUnit_Coord) {
|
||||
hasSpecifiedWidth = PR_TRUE;
|
||||
nscoord w = nsLayoutUtils::ComputeWidthValue(aRenderingContext,
|
||||
aFrame, 0, 0, 0, stylePos->mWidth);
|
||||
aFrame, 0, 0, 0, width);
|
||||
// Quirk: A cell with "nowrap" set and a coord value for the
|
||||
// width which is bigger than the intrinsic minimum width uses
|
||||
// that coord value as the minimum width.
|
||||
|
@ -139,9 +145,9 @@ GetWidthInfo(nsIRenderingContext *aRenderingContext,
|
|||
}
|
||||
prefCoord = NS_MAX(w, minCoord);
|
||||
} else if (unit == eStyleUnit_Percent) {
|
||||
prefPercent = stylePos->mWidth.GetPercentValue();
|
||||
prefPercent = width.GetPercentValue();
|
||||
} else if (unit == eStyleUnit_Enumerated && aIsCell) {
|
||||
switch (stylePos->mWidth.GetIntValue()) {
|
||||
switch (width.GetIntValue()) {
|
||||
case NS_STYLE_WIDTH_MAX_CONTENT:
|
||||
// 'width' only affects pref width, not min
|
||||
// width, so don't change anything
|
||||
|
|
|
@ -105,7 +105,8 @@ FixedTableLayoutStrategy::GetMinWidth(nsIRenderingContext* aRenderingContext)
|
|||
// do nothing
|
||||
} else {
|
||||
NS_ASSERTION(styleWidth->GetUnit() == eStyleUnit_Auto ||
|
||||
styleWidth->GetUnit() == eStyleUnit_Enumerated,
|
||||
styleWidth->GetUnit() == eStyleUnit_Enumerated ||
|
||||
styleWidth->IsCalcUnit(),
|
||||
"bad width");
|
||||
|
||||
// The 'table-layout: fixed' algorithm considers only cells
|
||||
|
@ -137,8 +138,8 @@ FixedTableLayoutStrategy::GetMinWidth(nsIRenderingContext* aRenderingContext)
|
|||
result -= spacing * (colSpan - 1);
|
||||
}
|
||||
}
|
||||
// else, for 'auto', '-moz-available', and '-moz-fit-content'
|
||||
// do nothing
|
||||
// else, for 'auto', '-moz-available', '-moz-fit-content',
|
||||
// and 'calc()', do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +252,8 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
|
|||
pctTotal += pct;
|
||||
} else {
|
||||
NS_ASSERTION(styleWidth->GetUnit() == eStyleUnit_Auto ||
|
||||
styleWidth->GetUnit() == eStyleUnit_Enumerated,
|
||||
styleWidth->GetUnit() == eStyleUnit_Enumerated ||
|
||||
styleWidth->IsCalcUnit(),
|
||||
"bad width");
|
||||
|
||||
// The 'table-layout: fixed' algorithm considers only cells
|
||||
|
@ -286,7 +288,8 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
|
|||
colFrame->AddPrefPercent(pct);
|
||||
pctTotal += pct;
|
||||
} else {
|
||||
// 'auto', '-moz-available', and '-moz-fit-content'
|
||||
// 'auto', '-moz-available', '-moz-fit-content', and
|
||||
// 'calc()'
|
||||
colWidth = unassignedMarker;
|
||||
}
|
||||
if (colWidth != unassignedMarker) {
|
||||
|
|
|
@ -679,9 +679,16 @@ nsIBox::AddCSSPrefSize(nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &a
|
|||
// (Handling the eStyleUnit_Enumerated types requires
|
||||
// GetPrefSize/GetMinSize methods that don't consider
|
||||
// (min-/max-/)(width/height) properties.)
|
||||
if (position->mWidth.GetUnit() == eStyleUnit_Coord) {
|
||||
aSize.width = position->mWidth.GetCoordValue();
|
||||
const nsStyleCoord &width = position->mWidth;
|
||||
if (width.GetUnit() == eStyleUnit_Coord) {
|
||||
aSize.width = width.GetCoordValue();
|
||||
aWidthSet = PR_TRUE;
|
||||
} else if (width.IsCalcUnit()) {
|
||||
if (!width.CalcHasPercent()) {
|
||||
// pass 0 for percentage basis since we know there are no %s
|
||||
aSize.width = nsRuleNode::ComputeComputedCalc(width, 0);
|
||||
aWidthSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (position->mHeight.GetUnit() == eStyleUnit_Coord) {
|
||||
|
|
|
@ -2,27 +2,27 @@
|
|||
|
||||
# Images of various sizes.
|
||||
== jpg-size-1x1.jpg jpg-size-1x1.png
|
||||
fails-if(winWidget) == jpg-size-2x2.jpg jpg-size-2x2.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-2x2.jpg jpg-size-2x2.png
|
||||
== jpg-size-3x3.jpg jpg-size-3x3.png
|
||||
== jpg-size-4x4.jpg jpg-size-4x4.png
|
||||
fails-if(winWidget) == jpg-size-5x5.jpg jpg-size-5x5.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-5x5.jpg jpg-size-5x5.png
|
||||
== jpg-size-6x6.jpg jpg-size-6x6.png
|
||||
fails-if(winWidget) == jpg-size-7x7.jpg jpg-size-7x7.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-7x7.jpg jpg-size-7x7.png
|
||||
== jpg-size-8x8.jpg jpg-size-8x8.png
|
||||
fails-if(winWidget) == jpg-size-9x9.jpg jpg-size-9x9.png
|
||||
fails-if(winWidget) == jpg-size-15x15.jpg jpg-size-15x15.png
|
||||
fails-if(winWidget) == jpg-size-16x16.jpg jpg-size-16x16.png
|
||||
fails-if(winWidget) == jpg-size-17x17.jpg jpg-size-17x17.png
|
||||
fails-if(winWidget) == jpg-size-31x31.jpg jpg-size-31x31.png
|
||||
fails-if(winWidget) == jpg-size-32x32.jpg jpg-size-32x32.png
|
||||
fails-if(winWidget) == jpg-size-33x33.jpg jpg-size-33x33.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-9x9.jpg jpg-size-9x9.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-15x15.jpg jpg-size-15x15.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-16x16.jpg jpg-size-16x16.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-17x17.jpg jpg-size-17x17.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-31x31.jpg jpg-size-31x31.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-32x32.jpg jpg-size-32x32.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-size-33x33.jpg jpg-size-33x33.png
|
||||
# Progressive encoding
|
||||
fails-if(winWidget) == jpg-progressive.jpg jpg-progressive.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-progressive.jpg jpg-progressive.png
|
||||
# Grayscale colorspace
|
||||
fails-if(winWidget) == jpg-gray.jpg jpg-gray.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-gray.jpg jpg-gray.png
|
||||
# CMYK colorspace
|
||||
fails-if(winWidget) == jpg-cmyk-1.jpg jpg-cmyk-1.png
|
||||
fails-if(winWidget) == jpg-cmyk-2.jpg jpg-cmyk-2.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-cmyk-1.jpg jpg-cmyk-1.png
|
||||
fails-if(xulRuntime.XPCOMABI=="x86-msvc") == jpg-cmyk-2.jpg jpg-cmyk-2.png
|
||||
== jpg-srgb-icc.jpg jpg-srgb-icc.png
|
||||
|
||||
# webcam-simulacrum.mjpg is a hand-edited file containing red.jpg and blue.jpg,
|
||||
|
|
|
@ -83,10 +83,6 @@ Tester.prototype = {
|
|||
let msg = baseMsg.replace("{elt}", "tab") +
|
||||
": " + lastTab.linkedBrowser.currentURI.spec;
|
||||
this.currentTest.addResult(new testResult(false, msg, "", false));
|
||||
if (gBrowser._removingTabs && gBrowser._removingTabs.indexOf(lastTab) > -1) {
|
||||
gBrowser._endRemoveTab(lastTab);
|
||||
continue;
|
||||
}
|
||||
gBrowser.removeTab(lastTab);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
*
|
||||
* The Original Code is Mozilla Mobile Browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
@ -23,6 +22,7 @@
|
|||
* Roy Frostig <rfrostig@mozilla.com>
|
||||
* Ben Combee <bcombee@mozilla.com>
|
||||
* Matt Brubeck <mbrubeck@mozilla.com>
|
||||
* Benjamin Stover <bstover@mozilla.com>
|
||||
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
|
@ -39,7 +39,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["Point","Rect"];
|
||||
let EXPORTED_SYMBOLS = ["Point", "Rect"];
|
||||
|
||||
/**
|
||||
* Simple Point class.
|
||||
|
@ -60,7 +60,7 @@ Point.prototype = {
|
|||
this.y = y;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
equals: function equals(x, y) {
|
||||
return this.x == x && this.y == y;
|
||||
},
|
||||
|
|
|
@ -83,9 +83,9 @@ DIRS += tests
|
|||
endif
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
Geometry.jsm \
|
||||
InlineSpellChecker.jsm \
|
||||
PopupNotifications.jsm \
|
||||
Geometry.jsm \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_PP_JS_MODULES = \
|
||||
|
|
|
@ -53,9 +53,9 @@ include $(topsrcdir)/config/rules.mk
|
|||
_BROWSER_TEST_FILES = \
|
||||
$(warning browser_keyevents_during_autoscrolling.js disabled due to frequent timeouts (bug 567950)) \
|
||||
browser_bug295977_autoscroll_overflow.js \
|
||||
browser_Geometry.js \
|
||||
browser_save_resend_postdata.js \
|
||||
browser_Services.js \
|
||||
browser_Geometry.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -5692,8 +5692,11 @@ DirectoryInstallLocation.prototype = {
|
|||
delete this._DirToIDMap[dir.path];
|
||||
delete this._IDToDirMap[aId];
|
||||
|
||||
if (!dir.exists())
|
||||
throw new Error("Attempt to uninstall unknown add-on " + aId);
|
||||
if (!dir.exists()) {
|
||||
WARN("Attempted to remove the directory for " + aId + " from " +
|
||||
this._name + " but it was already gone");
|
||||
return;
|
||||
}
|
||||
|
||||
dir.remove(true);
|
||||
},
|
||||
|
|
|
@ -133,6 +133,7 @@ function notifyInitialized() {
|
|||
}
|
||||
|
||||
function shutdown() {
|
||||
gCategories.shutdown();
|
||||
gSearchView.shutdown();
|
||||
gEventManager.shutdown();
|
||||
gViewController.shutdown();
|
||||
|
@ -793,6 +794,7 @@ function getAddonsAndInstalls(aType, aCallback) {
|
|||
var gCategories = {
|
||||
node: null,
|
||||
_search: null,
|
||||
_maybeHidden: null,
|
||||
|
||||
initialize: function() {
|
||||
this.node = document.getElementById("categories");
|
||||
|
@ -820,13 +822,21 @@ var gCategories = {
|
|||
}
|
||||
}, false);
|
||||
|
||||
var maybeHidden = ["addons://list/locale", "addons://list/searchengine"];
|
||||
gPendingInitializations += maybeHidden.length;
|
||||
maybeHidden.forEach(function(aId) {
|
||||
this._maybeHidden = ["addons://list/locale", "addons://list/searchengine"];
|
||||
gPendingInitializations += this._maybeHidden.length;
|
||||
this._maybeHidden.forEach(function(aId) {
|
||||
var type = gViewController.parseViewId(aId).param;
|
||||
getAddonsAndInstalls(type, function(aAddonsList, aInstallsList) {
|
||||
var hidden = (aAddonsList.length == 0 && aInstallsList.length == 0);
|
||||
var item = self.get(aId);
|
||||
|
||||
// Don't load view that is becoming hidden
|
||||
if (hidden && aId == gViewController.currentViewId)
|
||||
gViewController.loadView(VIEW_DEFAULT);
|
||||
|
||||
item.hidden = hidden;
|
||||
|
||||
if (aAddonsList.length > 0 || aInstallsList.length > 0) {
|
||||
self.get(aId).hidden = false;
|
||||
notifyInitialized();
|
||||
return;
|
||||
}
|
||||
|
@ -861,6 +871,15 @@ var gCategories = {
|
|||
});
|
||||
},
|
||||
|
||||
shutdown: function() {
|
||||
// Force persist of hidden state. See bug 15232
|
||||
var self = this;
|
||||
this._maybeHidden.forEach(function(aId) {
|
||||
var item = self.get(aId);
|
||||
item.setAttribute("hidden", !!item.hidden);
|
||||
});
|
||||
},
|
||||
|
||||
select: function(aId) {
|
||||
if (this.node.selectedItem &&
|
||||
this.node.selectedItem.value == aId)
|
||||
|
|
|
@ -114,11 +114,13 @@
|
|||
name="&view.discover.label;"/>
|
||||
<richlistitem id="category-languages" value="addons://list/locale"
|
||||
class="category"
|
||||
name="&view.locales.label;" hidden="true"/>
|
||||
name="&view.locales.label;"
|
||||
hidden="true" persist="hidden"/>
|
||||
<richlistitem id="category-searchengines"
|
||||
value="addons://list/searchengine"
|
||||
class="category"
|
||||
name="&view.searchengines.label;" hidden="true"/>
|
||||
name="&view.searchengines.label;"
|
||||
hidden="true" persist="hidden"/>
|
||||
<richlistitem id="category-extensions" value="addons://list/extension"
|
||||
class="category"
|
||||
name="&view.features.label;"/>
|
||||
|
|
|
@ -53,6 +53,7 @@ _TEST_FILES = \
|
|||
browser_bug562992.js \
|
||||
browser_bug567137.js \
|
||||
browser_bug572561.js \
|
||||
browser_bug577990.js \
|
||||
browser_dragdrop.js \
|
||||
browser_searching.js \
|
||||
browser_searching.xml \
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that the visible delay in showing the "Language" category occurs
|
||||
// very minimally
|
||||
|
||||
var gManagerWindow;
|
||||
var gCategoryUtilities;
|
||||
var gProvider;
|
||||
var gInstall;
|
||||
var gInstallProperties = [{
|
||||
name: "Locale Category Test",
|
||||
type: "locale"
|
||||
}];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gProvider = new MockProvider();
|
||||
|
||||
open_manager(null, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
close_manager(gManagerWindow, finish);
|
||||
}
|
||||
|
||||
function install_locale(aCallback) {
|
||||
gInstall = gProvider.createInstalls(gInstallProperties)[0];
|
||||
gInstall.addTestListener({
|
||||
onInstallEnded: function(aInstall) {
|
||||
gInstall.removeTestListener(this);
|
||||
aCallback();
|
||||
}
|
||||
});
|
||||
gInstall.install();
|
||||
}
|
||||
|
||||
function check_hidden(aExpectedHidden) {
|
||||
var hidden = !gCategoryUtilities.isTypeVisible("locale");
|
||||
is(hidden, !!aExpectedHidden, "Should have correct hidden state");
|
||||
}
|
||||
|
||||
function run_open_test(aTestSetup, aLoadHidden, aInitializedHidden, aSelected) {
|
||||
function loadCallback(aManagerWindow) {
|
||||
gManagerWindow = aManagerWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
check_hidden(aLoadHidden);
|
||||
}
|
||||
|
||||
function run() {
|
||||
open_manager(null, function() {
|
||||
check_hidden(aInitializedHidden);
|
||||
var selected = (gCategoryUtilities.selectedCategory == "locale");
|
||||
is(selected, !!aSelected, "Should have correct selected state");
|
||||
|
||||
run_next_test();
|
||||
}, loadCallback);
|
||||
}
|
||||
|
||||
close_manager(gManagerWindow, function() {
|
||||
// Allow for asynchronous functions to run before the manager opens
|
||||
aTestSetup ? aTestSetup(run) : run();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Tests that the locale category is hidden when there are no locales installed
|
||||
add_test(function() {
|
||||
run_open_test(null, true, true);
|
||||
});
|
||||
|
||||
// Tests that installing a locale while the Add-on Manager is open shows the
|
||||
// locale category
|
||||
add_test(function() {
|
||||
check_hidden(true);
|
||||
install_locale(function() {
|
||||
check_hidden(false);
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that the locale category is shown with no delay when restarting
|
||||
// Add-on Manager
|
||||
add_test(function() {
|
||||
run_open_test(null, false, false);
|
||||
});
|
||||
|
||||
// Tests that cancelling the locale install and restarting the Add-on Manager
|
||||
// causes the locale category to be hidden with an acceptable delay
|
||||
add_test(function() {
|
||||
gInstall.cancel();
|
||||
run_open_test(null, false, true)
|
||||
});
|
||||
|
||||
// Tests that the locale category is hidden with no delay when restarting
|
||||
// Add-on Manager
|
||||
add_test(function() {
|
||||
run_open_test(null, true, true);
|
||||
});
|
||||
|
||||
// Tests that installing a locale when the Add-on Manager is closed, and then
|
||||
// opening the Add-on Manager causes the locale category to be shown with an
|
||||
// acceptable delay
|
||||
add_test(function() {
|
||||
run_open_test(install_locale, true, false);
|
||||
});
|
||||
|
||||
// Tests that selection of the locale category persists
|
||||
add_test(function() {
|
||||
gCategoryUtilities.openType("locale", function() {
|
||||
run_open_test(null, false, false, true);
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that cancelling the locale install and restarting the Add-on Manager
|
||||
// causes the locale category to be hidden and not selected
|
||||
add_test(function() {
|
||||
gInstall.cancel();
|
||||
run_open_test(null, false, true);
|
||||
});
|
||||
|
|
@ -80,8 +80,11 @@ function wait_for_manager_load(aManagerWindow, aCallback) {
|
|||
}, false);
|
||||
}
|
||||
|
||||
function open_manager(aView, aCallback) {
|
||||
function open_manager(aView, aCallback, aLoadCallback) {
|
||||
function setup_manager(aManagerWindow) {
|
||||
if (aLoadCallback)
|
||||
aLoadCallback(aManagerWindow);
|
||||
|
||||
if (aView)
|
||||
aManagerWindow.loadView(aView);
|
||||
|
||||
|
@ -119,8 +122,15 @@ function close_manager(aManagerWindow, aCallback) {
|
|||
aManagerWindow.close();
|
||||
}
|
||||
|
||||
function restart_manager(aManagerWindow, aView, aCallback) {
|
||||
close_manager(aManagerWindow, function() { open_manager(aView, aCallback); });
|
||||
function restart_manager(aManagerWindow, aView, aCallback, aLoadCallback) {
|
||||
if (!aManagerWindow) {
|
||||
open_manager(aView, aCallback, aLoadCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
close_manager(aManagerWindow, function() {
|
||||
open_manager(aView, aCallback, aLoadCallback);
|
||||
});
|
||||
}
|
||||
|
||||
function is_element_visible(aWindow, aElement, aExpected, aMsg) {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that we recover gracefully from an extension directory disappearing
|
||||
// when we were expecting to uninstall it.
|
||||
|
||||
var addon1 = {
|
||||
id: "addon1@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test 1",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
var addon2 = {
|
||||
id: "addon2@tests.mozilla.org",
|
||||
version: "2.0",
|
||||
name: "Test 2",
|
||||
targetApplications: [{
|
||||
id: "toolkit@mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2");
|
||||
|
||||
var dest = profileDir.clone();
|
||||
dest.append("addon1@tests.mozilla.org");
|
||||
writeInstallRDFToDir(addon1, dest);
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
|
||||
a1.uninstall();
|
||||
|
||||
shutdownManager();
|
||||
|
||||
var dest = profileDir.clone();
|
||||
dest.append("addon1@tests.mozilla.org");
|
||||
dest.remove(true);
|
||||
|
||||
dest = profileDir.clone();
|
||||
dest.append("addon2@tests.mozilla.org");
|
||||
writeInstallRDFToDir(addon2, dest);
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||
"addon2@tests.mozilla.org"],
|
||||
function([a1, a2]) {
|
||||
// Addon1 should no longer be installed
|
||||
do_check_eq(a1, null);
|
||||
|
||||
// Addon2 should have been detected
|
||||
do_check_neq(a2, null);
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -96,13 +96,13 @@ protected:
|
|||
};
|
||||
|
||||
#define SET_FORMATETC(fe, cf, td, asp, li, med) \
|
||||
{\
|
||||
(fe).cfFormat=cf;\
|
||||
(fe).ptd=td;\
|
||||
(fe).dwAspect=asp;\
|
||||
(fe).lindex=li;\
|
||||
(fe).tymed=med;\
|
||||
}
|
||||
{\
|
||||
(fe).cfFormat=cf;\
|
||||
(fe).ptd=td;\
|
||||
(fe).dwAspect=asp;\
|
||||
(fe).lindex=li;\
|
||||
(fe).tymed=med;\
|
||||
}
|
||||
|
||||
|
||||
#endif // nsClipboard_h__
|
||||
|
|
|
@ -79,6 +79,9 @@
|
|||
#include "nsTString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
PR_STATIC_ASSERT(sizeof(PRUnichar) == 2);
|
||||
PR_STATIC_ASSERT(sizeof(nsString::char_type) == 2);
|
||||
PR_STATIC_ASSERT(sizeof(nsCString::char_type) == 1);
|
||||
|
||||
/**
|
||||
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
|
||||
|
|
Загрузка…
Ссылка в новой задаче