Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-06-06 12:46:50 -04:00
commit ccdd37d975
95 changed files with 4769 additions and 114 deletions

View File

@ -71,8 +71,8 @@
<!-- Buttons -->
<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="buttons">
#ifdef XP_UNIX
<button id="errorCancel" label="&restorepage.cancelButton;"
accesskey="&restorepage.cancel.access;"
<button id="errorCancel" label="&restorepage.closeButton;"
accesskey="&restorepage.close.access;"
oncommand="startNewSession();"/>
<button id="errorTryAgain" label="&restorepage.tryagainButton;"
accesskey="&restorepage.restore.access;"
@ -81,8 +81,8 @@
<button id="errorTryAgain" label="&restorepage.tryagainButton;"
accesskey="&restorepage.restore.access;"
oncommand="restoreSession();"/>
<button id="errorCancel" label="&restorepage.cancelButton;"
accesskey="&restorepage.cancel.access;"
<button id="errorCancel" label="&restorepage.closeButton;"
accesskey="&restorepage.close.access;"
oncommand="startNewSession();"/>
#endif
</hbox>

View File

@ -123,6 +123,7 @@ let DebuggerController = {
this._remoteConnectionTimeout = window.setTimeout(function() {
// If we couldn't connect to any server yet, try again...
if (!DebuggerController.activeThread) {
DebuggerController._onRemoteConnectionTimeout();
DebuggerController._connect();
}
}, Prefs.remoteTimeout);
@ -130,6 +131,14 @@ let DebuggerController = {
return true;
},
/**
* Called when a remote connection timeout occurs.
*/
_onRemoteConnectionTimeout: function DC__onRemoteConnectionTimeout() {
Cu.reportError("Couldn't connect to " +
Prefs.remoteHost + ":" + Prefs.remotePort);
},
/**
* Initializes a debugger client and connects it to the debugger server,
* wiring event handlers as necessary.
@ -917,7 +926,7 @@ SourceScripts.prototype = {
}
// Use JS mode for files with .js and .jsm extensions.
if (/\.jsm?$/.test(this._trimUrlQuery(aUrl))) {
if (/\.jsm?$/.test(this.trimUrlQuery(aUrl))) {
DebuggerView.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
} else {
DebuggerView.editor.setMode(SourceEditor.MODES.HTML);
@ -925,50 +934,121 @@ SourceScripts.prototype = {
},
/**
* Trims the id selector or query part of a url string, if necessary.
* Trims the query part or reference identifier of a url string, if necessary.
*
* @param string aUrl
* The script url.
* @return string
* The url with the trimmed query.
*/
_trimUrlQuery: function SS__trimUrlQuery(aUrl) {
let q = aUrl.indexOf('#');
if (q === -1) q = aUrl.indexOf('?');
if (q === -1) q = aUrl.indexOf('&');
trimUrlQuery: function SS_trimUrlQuery(aUrl) {
let length = aUrl.length;
let q1 = aUrl.indexOf('?');
let q2 = aUrl.indexOf('&');
let q3 = aUrl.indexOf('#');
let q = Math.min(q1 !== -1 ? q1 : length,
q2 !== -1 ? q2 : length,
q3 !== -1 ? q3 : length);
if (q > -1) {
return aUrl.slice(0, q);
}
return aUrl;
return aUrl.slice(0, q);
},
/**
* Gets the prePath for a script URL.
* Trims as much as possible from a URL, while keeping the result unique
* in the Debugger View scripts container.
*
* @param string aUrl
* The script url.
* @param string | nsIURL aUrl
* The script URL.
* @param string aLabel [optional]
* The resulting label at each step.
* @param number aSeq [optional]
* The current iteration step.
* @return string
* The script prePath if the url is valid, null otherwise.
* The resulting label at the final step.
*/
_getScriptPrePath: function SS__getScriptDomain(aUrl) {
try {
return Services.io.newURI(aUrl, null, null).prePath + "/";
} catch (e) {
_trimURL: function SS__trimURL(aUrl, aLabel, aSeq) {
if (!(aUrl instanceof Ci.nsIURL)) {
try {
// Use an nsIURL to parse all the url path parts.
aUrl = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
} catch (e) {
// This doesn't look like a url, or nsIURL can't handle it.
return aUrl;
}
}
return null;
if (!aSeq) {
let name = aUrl.fileName;
if (name) {
// This is a regular file url, get only the file name (contains the
// base name and extension if available).
// If this url contains an invalid query, unfortunately nsIURL thinks
// it's part of the file extension. It must be removed.
aLabel = aUrl.fileName.replace(/\&.*/, "");
} else {
// This is not a file url, hence there is no base name, nor extension.
// Proceed using other available information.
aLabel = "";
}
aSeq = 1;
}
// If we have a label and it doesn't start with a query...
if (aLabel && aLabel.indexOf("?") !== 0) {
if (DebuggerView.Scripts.containsIgnoringQuery(aUrl.spec)) {
// A page may contain multiple requests to the same url but with different
// queries. It would be redundant to show each one.
return aLabel;
}
if (!DebuggerView.Scripts.containsLabel(aLabel)) {
// We found the shortest unique label for the url.
return aLabel;
}
}
// Append the url query.
if (aSeq === 1) {
let query = aUrl.query;
if (query) {
return this._trimURL(aUrl, aLabel + "?" + query, aSeq + 1);
}
aSeq++;
}
// Append the url reference.
if (aSeq === 2) {
let ref = aUrl.ref;
if (ref) {
return this._trimURL(aUrl, aLabel + "#" + aUrl.ref, aSeq + 1);
}
aSeq++;
}
// Prepend the url directory.
if (aSeq === 3) {
let dir = aUrl.directory;
if (dir) {
return this._trimURL(aUrl, dir.replace(/^\//, "") + aLabel, aSeq + 1);
}
aSeq++;
}
// Prepend the hostname and port number.
if (aSeq === 4) {
let host = aUrl.hostPort;
if (host) {
return this._trimURL(aUrl, host + "/" + aLabel, aSeq + 1);
}
aSeq++;
}
// Use the whole url spec but ignoring the reference.
if (aSeq === 5) {
return this._trimURL(aUrl, aUrl.specIgnoringRef, aSeq + 1);
}
// Give up.
return aUrl.spec;
},
/**
* Gets a unique, simplified label from a script url.
* ex: a). ici://some.address.com/random/subrandom/
* b). ni://another.address.org/random/subrandom/page.html
* c). san://interesting.address.gro/random/script.js
* d). si://interesting.address.moc/random/another/script.js
* =>
* a). subrandom/
* b). page.html
* c). script.js
* d). another/script.js
*
* @param string aUrl
* The script url.
@ -979,30 +1059,7 @@ SourceScripts.prototype = {
* The simplified label.
*/
_getScriptLabel: function SS__getScriptLabel(aUrl, aHref) {
let url = this._trimUrlQuery(aUrl);
if (this._labelsCache[url]) {
return this._labelsCache[url];
}
let content = window.parent.content;
let domain = content ? content.location.href : this._getScriptPrePath(aUrl);
let href = aHref || domain;
let pathElements = url.split("/");
let label = pathElements.pop() || (pathElements.pop() + "/");
// If the label as a leaf name is already present in the scripts list.
if (DebuggerView.Scripts.containsLabel(label)) {
label = url.replace(href.substring(0, href.lastIndexOf("/") + 1), "");
// If the path/to/script is exactly the same, we're in different domains.
if (DebuggerView.Scripts.containsLabel(label)) {
label = url;
}
}
return this._labelsCache[url] = label;
return this._labelsCache[aUrl] || (this._labelsCache[aUrl] = this._trimURL(aUrl));
},
/**

View File

@ -157,6 +157,31 @@ ScriptsView.prototype = {
this._onScriptsSearch({});
},
/**
* Checks whether the script with the specified URL is among the scripts
* known to the debugger (ignoring the query & reference).
*
* @param string aUrl
* The script URL.
* @return boolean
*/
containsIgnoringQuery: function DVS_containsIgnoringQuery(aUrl) {
let sourceScripts = DebuggerController.SourceScripts;
aUrl = sourceScripts.trimUrlQuery(aUrl);
if (this._tmpScripts.some(function(element) {
return sourceScripts.trimUrlQuery(element.script.url) == aUrl;
})) {
return true;
}
if (this.scriptLocations.some(function(url) {
return sourceScripts.trimUrlQuery(url) == aUrl;
})) {
return true;
}
return false;
},
/**
* Checks whether the script with the specified URL is among the scripts
* known to the debugger and shown in the list.
@ -346,7 +371,7 @@ ScriptsView.prototype = {
aLabel, aScript, aIndex, aSelectIfEmptyFlag)
{
// Make sure we don't duplicate anything.
if (aLabel == "null" || this.containsLabel(aLabel)) {
if (aLabel == "null" || this.containsLabel(aLabel) || this.contains(aScript.url)) {
return;
}

View File

@ -7,6 +7,7 @@
var gWindow = null;
var gTab = null;
var gRemotePort = null;
var gAutoConnect = null;
const TEST_URL = EXAMPLE_URL + "browser_dbg_iframes.html";
@ -17,6 +18,11 @@ function test() {
gWindow = aWindow;
let gDebugger = gWindow.contentWindow;
info("Current remote port: " +
Services.prefs.getIntPref("devtools.debugger.remote-port"));
info("Current autoconnect flag: " +
Services.prefs.getBoolPref("devtools.debugger.remote-autoconnect"));
is(gDebugger.document.getElementById("close").getAttribute("hidden"), "true",
"The close button should be hidden in a remote debugger.");
@ -60,21 +66,46 @@ function test() {
}
DebuggerServer.closeListener();
gRemotePort = Services.prefs.getIntPref("devtools.debugger.remote-port");
gAutoConnect = Services.prefs.getBoolPref("devtools.debugger.remote-autoconnect");
Services.prefs.setBoolPref("devtools.debugger.remote-autoconnect", true);
// Open the listener at some point in the future to test automatic reconnect.
window.setTimeout(function() {
DebuggerServer.openListener(
Services.prefs.getIntPref("devtools.debugger.remote-port"));
}, Math.random() * 1000);
openListener(gRemotePort + 1);
});
}
let attempts = 0;
function openListener(port) {
Services.prefs.setIntPref("devtools.debugger.remote-port", port);
Services.prefs.setBoolPref("devtools.debugger.remote-autoconnect", true);
info("Attempting to open a new listener on port " + port);
try {
info("Closing listener...");
DebuggerServer.closeListener();
info("Opening listener...");
DebuggerServer.openListener(port);
} catch (e) {
info(e);
info("Exception caught when opening listener on port " + port);
info("Retrying with port " + (++port));
if (++attempts < 100) {
DebuggerServer.closeListener();
openListener(port);
} else {
ok(false, "Timed out while opening a listener.");
}
}
}
registerCleanupFunction(function() {
Services.prefs.setIntPref("devtools.debugger.remote-port", gRemotePort);
Services.prefs.setBoolPref("devtools.debugger.remote-autoconnect", gAutoConnect);
removeTab(gTab);
gWindow = null;
gTab = null;
gRemotePort = null;
gAutoConnect = null;
});

View File

@ -37,21 +37,32 @@ function testScriptLabelShortening() {
vs.empty();
vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
is(ss._trimUrlQuery("a/b/c.d?test=1&random=4"), "a/b/c.d",
is(ss.trimUrlQuery("a/b/c.d?test=1&random=4#reference"), "a/b/c.d",
"Trimming the url query isn't done properly.");
let urls = [
{ href: "ichi://some.address.com/random/", leaf: "subrandom/" },
{ href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
{ href: "san://interesting.address.gro/random/", leaf: "script.js" },
{ href: "shi://interesting.address.moc/random/", leaf: "script.js" },
{ href: "shi://interesting.address.moc/random/", leaf: "x/script.js" },
{ href: "shi://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
{ href: "shi://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2", dupe: true },
{ href: "shi://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3", dupe: true },
{ href: "go://random/", leaf: "script_t1.js&a=1&b=2&c=3" },
{ href: "roku://random/", leaf: "script_t2.js#id" },
{ href: "nana://random/", leaf: "script_t3.js#id?a=1&b=2" }
{ href: "http://some.address.com/random/", leaf: "subrandom/" },
{ href: "http://some.address.com/random/", leaf: "suprandom/?a=1" },
{ href: "http://some.address.com/random/", leaf: "?a=1" },
{ href: "https://another.address.org/random/subrandom/", leaf: "page.html" },
{ href: "ftp://interesting.address.org/random/", leaf: "script.js" },
{ href: "ftp://interesting.address.com/random/", leaf: "script.js" },
{ href: "ftp://interesting.address.com/random/", leaf: "x/script.js" },
{ href: "ftp://interesting.address.com/random/", leaf: "x/y/script.js?a=1" },
{ href: "ftp://interesting.address.com/random/x/", leaf: "y/script.js?a=1&b=2", dupe: true },
{ href: "ftp://interesting.address.com/random/x/y/", leaf: "script.js?a=1&b=2&c=3", dupe: true },
{ href: "ftp://interesting.address.com/random/", leaf: "x/y/script.js?a=2", dupe: true },
{ href: "ftp://interesting.address.com/random/x/", leaf: "y/script.js?a=2&b=3", dupe: true },
{ href: "ftp://interesting.address.com/random/x/y/", leaf: "script.js?a=2&b=3&c=4", dupe: true },
{ href: "file://random/", leaf: "script_t1.js&a=1&b=2&c=3" },
{ href: "file://random/", leaf: "script_t2_1.js#id" },
{ href: "file://random/", leaf: "script_t2_2.js?a" },
{ href: "file://random/", leaf: "script_t2_3.js&b" },
{ href: "resource://random/", leaf: "script_t3_1.js#id?a=1&b=2" },
{ href: "resource://random/", leaf: "script_t3_2.js?a=1&b=2#id" },
{ href: "resource://random/", leaf: "script_t3_3.js&a=1&b=2#id" }
];
urls.forEach(function(url) {
@ -62,31 +73,55 @@ function testScriptLabelShortening() {
});
executeSoon(function() {
info("Script labels:");
info(vs.scriptLabels.toSource());
info("Script locations:");
info(vs.scriptLocations.toSource());
urls.forEach(function(url) {
let loc = url.href + url.leaf;
ok(url.dupe || vs.contains(loc), "Script url is incorrect: " + loc);
if (url.dupe) {
ok(!vs.contains(loc), "Shouldn't contain script: " + loc);
} else {
ok(vs.contains(loc), "Should contain script: " + loc);
}
});
ok(gDebugger.DebuggerView.Scripts.containsLabel("subrandom/"),
ok(gDebugger.DebuggerView.Scripts.containsLabel("random/subrandom/"),
"Script (0) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("page.html"),
ok(gDebugger.DebuggerView.Scripts.containsLabel("random/suprandom/?a=1"),
"Script (1) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script.js"),
ok(gDebugger.DebuggerView.Scripts.containsLabel("random/?a=1"),
"Script (2) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("shi://interesting.address.moc/random/script.js"),
ok(gDebugger.DebuggerView.Scripts.containsLabel("page.html"),
"Script (3) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("x/script.js"),
"Script (4) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("x/y/script.js"),
"Script (5) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t1.js"),
"Script (6) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t2.js"),
"Script (7) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t3.js"),
"Script (8) label is incorrect.");
is(vs._scripts.itemCount, 9,
ok(gDebugger.DebuggerView.Scripts.containsLabel("script.js"),
"Script (4) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("random/script.js"),
"Script (5) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("random/x/script.js"),
"Script (6) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script.js?a=1"),
"Script (7) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t1.js"),
"Script (8) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t2_1.js"),
"Script (9) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t2_2.js"),
"Script (10) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t2_3.js"),
"Script (11) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t3_1.js"),
"Script (12) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t3_2.js"),
"Script (13) label is incorrect.");
ok(gDebugger.DebuggerView.Scripts.containsLabel("script_t3_3.js"),
"Script (14) label is incorrect.");
is(vs._scripts.itemCount, urls.filter(function(url) !url.dupe).length,
"Didn't get the correct number of scripts in the list.");
closeDebuggerAndFinish();

View File

@ -14,8 +14,8 @@
<!ENTITY restorepage.tryagainButton "Restore">
<!ENTITY restorepage.restore.access "R">
<!ENTITY restorepage.cancelButton "Start New Session">
<!ENTITY restorepage.cancel.access "S">
<!ENTITY restorepage.closeButton "Close">
<!ENTITY restorepage.close.access "C">
<!ENTITY restorepage.restoreHeader "Restore">
<!ENTITY restorepage.listHeader "Windows and Tabs">

View File

@ -16,13 +16,16 @@
padding: 0;
}
#scripts {
max-width: 350px;
}
/**
* Lists and headers
*/
.list-item {
padding: 2px;
font: -moz-list;
}
.list-item.selected {
@ -48,6 +51,7 @@
}
.dbg-stackframe-name {
-moz-padding-end: 4px;
font-weight: 600;
}
@ -65,7 +69,6 @@
.details {
-moz-margin-start: 10px;
font: -moz-list;
}
/**
@ -75,7 +78,6 @@
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
font: -moz-list;
}
.scope > .title > .arrow {

View File

@ -18,13 +18,16 @@
padding: 0;
}
#scripts {
max-width: 350px;
}
/**
* Lists and headers
*/
.list-item {
padding: 2px;
font: -moz-list;
}
.list-item.selected {
@ -50,6 +53,7 @@
}
.dbg-stackframe-name {
-moz-padding-end: 4px;
font-weight: 600;
}
@ -67,7 +71,6 @@
.details {
-moz-margin-start: 10px;
font: -moz-list;
}
/**
@ -77,7 +80,6 @@
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
font: -moz-list;
}
.scope > .title > .arrow {

View File

@ -16,13 +16,16 @@
padding: 0;
}
#scripts {
max-width: 350px;
}
/**
* Lists and headers
*/
.list-item {
padding: 2px;
font: -moz-list;
}
.list-item.selected {
@ -48,6 +51,7 @@
}
.dbg-stackframe-name {
-moz-padding-end: 4px;
font-weight: 600;
}
@ -65,7 +69,6 @@
.details {
-moz-margin-start: 10px;
font: -moz-list;
}
/**
@ -75,7 +78,6 @@
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
font: -moz-list;
}
.scope > .title > .arrow {

View File

@ -236,6 +236,12 @@ private:
#define NS_EVENT_STATE_FULL_SCREEN_ANCESTOR NS_DEFINE_EVENT_STATE_MACRO(35)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(36)
// Content is in the optimum region.
#define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(37)
// Content is in the suboptimal region.
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
// Content is in the sub-suboptimal region.
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(39)
/**
* NOTE: do not go over 63 without updating nsEventStates::InternalType!

View File

@ -26,6 +26,7 @@ enum FormControlsTypes {
NS_FORM_SELECT,
NS_FORM_TEXTAREA,
NS_FORM_OBJECT,
NS_FORM_METER,
eFormControlsWithoutSubTypesMax,
// After this, all types will have sub-types which introduce new enum lists.
// eFormControlsWithoutSubTypesMax let us know if the previous types values
@ -243,13 +244,12 @@ bool
nsIFormControl::IsLabelableControl() const
{
// TODO: keygen should be in that list, see bug 101019.
// TODO: meter should be added, see bug 555985.
// TODO: NS_FORM_INPUT_HIDDEN should be removed, see bug 597650.
PRUint32 type = GetType();
return type & NS_FORM_INPUT_ELEMENT ||
type & NS_FORM_BUTTON_ELEMENT ||
// type == NS_FORM_KEYGEN ||
// type == NS_FORM_METER ||
type == NS_FORM_METER ||
type == NS_FORM_OUTPUT ||
type == NS_FORM_SELECT ||
type == NS_FORM_TEXTAREA;

View File

@ -58,6 +58,7 @@ CPPSRCS = \
nsHTMLMenuElement.cpp \
nsHTMLMenuItemElement.cpp \
nsHTMLMetaElement.cpp \
nsHTMLMeterElement.cpp \
nsHTMLModElement.cpp \
nsHTMLObjectElement.cpp \
nsHTMLOListElement.cpp \

View File

@ -3466,7 +3466,8 @@ nsGenericHTMLFormElement::CanBeDisabled() const
return
type != NS_FORM_LABEL &&
type != NS_FORM_OBJECT &&
type != NS_FORM_OUTPUT;
type != NS_FORM_OUTPUT &&
type != NS_FORM_METER;
}
bool

View File

@ -1544,6 +1544,7 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Map)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu)
NS_DECLARE_NS_NEW_HTML_ELEMENT(MenuItem)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Meter)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Object)
NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Option)

View File

@ -128,7 +128,8 @@ nsHTMLFieldSetElement::MatchListedElements(nsIContent* aContent, PRInt32 aNamesp
nsIAtom* aAtom, void* aData)
{
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
return formControl && formControl->GetType() != NS_FORM_LABEL;
return formControl && formControl->GetType() != NS_FORM_LABEL &&
formControl->GetType() != NS_FORM_METER;
}
NS_IMETHODIMP

View File

@ -191,6 +191,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
//
// NS_FORM_INPUT_IMAGE
// NS_FORM_LABEL
// NS_FORM_METER
return false;
}

View File

@ -0,0 +1,480 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
* Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
* Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
* Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLMeterElement.h"
#include "nsGenericHTMLElement.h"
#include "nsAttrValue.h"
#include "nsEventStateManager.h"
#include "nsAlgorithm.h"
class nsHTMLMeterElement : public nsGenericHTMLFormElement,
public nsIDOMHTMLMeterElement
{
public:
nsHTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLMeterElement();
/* nsISupports */
NS_DECL_ISUPPORTS_INHERITED
/* nsIDOMNode */
NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
/* nsIDOMElement */
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
/* nsIDOMHTMLElement */
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
/* nsIDOMHTMLMeterElement */
NS_DECL_NSIDOMHTMLMETERELEMENT
/* nsIFormControl */
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_METER; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
virtual nsEventStates IntrinsicState() const;
nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const;
bool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
const nsAString& aValue, nsAttrValue& aResult);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
private:
static const double kDefaultValue;
static const double kDefaultMin;
static const double kDefaultMax;
/**
* Returns the optimum state of the element.
* NS_EVENT_STATE_OPTIMUM if the actual value is in the optimum region.
* NS_EVENT_STATE_SUB_OPTIMUM if the actual value is in the sub-optimal region.
* NS_EVENT_STATE_SUB_SUB_OPTIMUM if the actual value is in the sub-sub-optimal region.
*
* @return the optimum state of the element.
*/
nsEventStates GetOptimumState() const;
/* @return the minimum value */
double GetMin() const;
/* @return the maximum value */
double GetMax() const;
/* @return the actual value */
double GetValue() const;
/* @return the low value */
double GetLow() const;
/* @return the high value */
double GetHigh() const;
/* @return the optimum value */
double GetOptimum() const;
};
const double nsHTMLMeterElement::kDefaultValue = 0.0;
const double nsHTMLMeterElement::kDefaultMin = 0.0;
const double nsHTMLMeterElement::kDefaultMax = 1.0;
NS_IMPL_NS_NEW_HTML_ELEMENT(Meter)
nsHTMLMeterElement::nsHTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLFormElement(aNodeInfo)
{
}
nsHTMLMeterElement::~nsHTMLMeterElement()
{
}
NS_IMPL_ADDREF_INHERITED(nsHTMLMeterElement, nsGenericElement)
NS_IMPL_RELEASE_INHERITED(nsHTMLMeterElement, nsGenericElement)
DOMCI_NODE_DATA(HTMLMeterElement, nsHTMLMeterElement)
NS_INTERFACE_TABLE_HEAD(nsHTMLMeterElement)
NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLMeterElement,
nsIDOMHTMLMeterElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMeterElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMeterElement)
NS_IMPL_ELEMENT_CLONE(nsHTMLMeterElement)
NS_IMETHODIMP
nsHTMLMeterElement::Reset()
{
/* The meter element is not resettable. */
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
{
/* The meter element is not submittable. */
return NS_OK;
}
nsEventStates
nsHTMLMeterElement::IntrinsicState() const
{
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
state |= GetOptimumState();
return state;
}
bool
nsHTMLMeterElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
const nsAString& aValue, nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max ||
aAttribute == nsGkAtoms::min || aAttribute == nsGkAtoms::low ||
aAttribute == nsGkAtoms::high || aAttribute == nsGkAtoms::optimum) {
return aResult.ParseDoubleValue(aValue);
}
}
return nsGenericHTMLFormElement::ParseAttribute(aNamespaceID, aAttribute,
aValue, aResult);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
return nsGenericHTMLFormElement::GetForm(aForm);
}
/*
* Value getters :
* const getters used by XPCOM methods and by IntrinsicState
*/
double
nsHTMLMeterElement::GetMin() const
{
/**
* If the attribute min is defined, the minimum is this value.
* Otherwise, the minimum is the default value.
*/
const nsAttrValue* attrMin = mAttrsAndChildren.GetAttr(nsGkAtoms::min);
if (attrMin && attrMin->Type() == nsAttrValue::eDoubleValue) {
return attrMin->GetDoubleValue();
}
return kDefaultMin;
}
double
nsHTMLMeterElement::GetMax() const
{
/**
* If the attribute max is defined, the maximum is this value.
* Otherwise, the maximum is the default value.
* If the maximum value is less than the minimum value,
* the maximum value is the same as the minimum value.
*/
double max;
const nsAttrValue* attrMax = mAttrsAndChildren.GetAttr(nsGkAtoms::max);
if (attrMax && attrMax->Type() == nsAttrValue::eDoubleValue) {
max = attrMax->GetDoubleValue();
} else {
max = kDefaultMax;
}
return NS_MAX(max, GetMin());
}
double
nsHTMLMeterElement::GetValue() const
{
/**
* If the attribute value is defined, the actual value is this value.
* Otherwise, the actual value is the default value.
* If the actual value is less than the minimum value,
* the actual value is the same as the minimum value.
* If the actual value is greater than the maximum value,
* the actual value is the same as the maximum value.
*/
double value;
const nsAttrValue* attrValue = mAttrsAndChildren.GetAttr(nsGkAtoms::value);
if (attrValue && attrValue->Type() == nsAttrValue::eDoubleValue) {
value = attrValue->GetDoubleValue();
} else {
value = kDefaultValue;
}
double min = GetMin();
if (value <= min) {
return min;
}
return NS_MIN(value, GetMax());
}
double
nsHTMLMeterElement::GetLow() const
{
/**
* If the low value is defined, the low value is this value.
* Otherwise, the low value is the minimum value.
* If the low value is less than the minimum value,
* the low value is the same as the minimum value.
* If the low value is greater than the maximum value,
* the low value is the same as the maximum value.
*/
double min = GetMin();
const nsAttrValue* attrLow = mAttrsAndChildren.GetAttr(nsGkAtoms::low);
if (!attrLow || attrLow->Type() != nsAttrValue::eDoubleValue) {
return min;
}
double low = attrLow->GetDoubleValue();
if (low <= min) {
return min;
}
return NS_MIN(low, GetMax());
}
double
nsHTMLMeterElement::GetHigh() const
{
/**
* If the high value is defined, the high value is this value.
* Otherwise, the high value is the maximum value.
* If the high value is less than the low value,
* the high value is the same as the low value.
* If the high value is greater than the maximum value,
* the high value is the same as the maximum value.
*/
double max = GetMax();
const nsAttrValue* attrHigh = mAttrsAndChildren.GetAttr(nsGkAtoms::high);
if (!attrHigh || attrHigh->Type() != nsAttrValue::eDoubleValue) {
return max;
}
double high = attrHigh->GetDoubleValue();
if (high >= max) {
return max;
}
return NS_MAX(high, GetLow());
}
double
nsHTMLMeterElement::GetOptimum() const
{
/**
* If the optimum value is defined, the optimum value is this value.
* Otherwise, the optimum value is the midpoint between
* the minimum value and the maximum value :
* min + (max - min)/2 = (min + max)/2
* If the optimum value is less than the minimum value,
* the optimum value is the same as the minimum value.
* If the optimum value is greater than the maximum value,
* the optimum value is the same as the maximum value.
*/
double max = GetMax();
double min = GetMin();
const nsAttrValue* attrOptimum =
mAttrsAndChildren.GetAttr(nsGkAtoms::optimum);
if (!attrOptimum || attrOptimum->Type() != nsAttrValue::eDoubleValue) {
return (min + max) / 2.0;
}
double optimum = attrOptimum->GetDoubleValue();
if (optimum <= min) {
return min;
}
return NS_MIN(optimum, max);
}
/*
* XPCOM methods
*/
NS_IMETHODIMP
nsHTMLMeterElement::GetMin(double* aValue)
{
*aValue = GetMin();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetMin(double aValue)
{
return SetDoubleAttr(nsGkAtoms::min, aValue);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetMax(double* aValue)
{
*aValue = GetMax();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetMax(double aValue)
{
return SetDoubleAttr(nsGkAtoms::max, aValue);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetValue(double* aValue)
{
*aValue = GetValue();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetValue(double aValue)
{
return SetDoubleAttr(nsGkAtoms::value, aValue);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetLow(double* aValue)
{
*aValue = GetLow();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetLow(double aValue)
{
return SetDoubleAttr(nsGkAtoms::low, aValue);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetHigh(double* aValue)
{
*aValue = GetHigh();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetHigh(double aValue)
{
return SetDoubleAttr(nsGkAtoms::high, aValue);
}
NS_IMETHODIMP
nsHTMLMeterElement::GetOptimum(double* aValue)
{
*aValue = GetOptimum();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMeterElement::SetOptimum(double aValue)
{
return SetDoubleAttr(nsGkAtoms::optimum, aValue);
}
nsEventStates
nsHTMLMeterElement::GetOptimumState() const
{
/*
* If the optimum value is in [minimum, low[,
* return if the value is in optimal, suboptimal or sub-suboptimal region
*
* If the optimum value is in [low, high],
* return if the value is in optimal or suboptimal region
*
* If the optimum value is in ]high, maximum],
* return if the value is in optimal, suboptimal or sub-suboptimal region
*/
double value = GetValue();
double low = GetLow();
double high = GetHigh();
double optimum = GetOptimum();
if (optimum < low) {
if (value < low) {
return NS_EVENT_STATE_OPTIMUM;
}
if (value <= high) {
return NS_EVENT_STATE_SUB_OPTIMUM;
}
return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
}
if (optimum > high) {
if (value > high) {
return NS_EVENT_STATE_OPTIMUM;
}
if (value >= low) {
return NS_EVENT_STATE_SUB_OPTIMUM;
}
return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
}
// optimum in [low, high]
if (value >= low && value <= high) {
return NS_EVENT_STATE_OPTIMUM;
}
return NS_EVENT_STATE_SUB_OPTIMUM;
}

View File

@ -264,6 +264,8 @@ _TEST_FILES = \
test_bug742030.html \
test_bug742549.html \
test_bug745685.html \
test_bug657938.html \
test_bug660238.html \
test_input_file_picker.html \
$(NULL)

View File

@ -400,12 +400,11 @@ var forms = [
var elementNames = [
'button', 'fieldset', 'input', 'label', 'object', 'output', 'select',
'textarea',
'textarea', 'meter'
];
var todoElements = [
['keygen', 'Keygen'],
['meter', 'Meter'],
];
for each(var e in todoElements) {

View File

@ -178,6 +178,7 @@ HTML_TAG("mark", "");
HTML_TAG("marquee", "Div");
HTML_TAG("menu", "Menu");
HTML_TAG("meta", "Meta");
HTML_TAG("meter", "Meter");
HTML_TAG("multicol", "Span");
HTML_TAG("nav", "")
HTML_TAG("nobr", "");

View File

@ -0,0 +1,393 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=657938
-->
<head>
<title>Test for Bug 657938</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<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=657938">Mozilla Bug 657938</a>
<p id="display"></p>
<iframe name="submit_frame" style="visibility: hidden;"></iframe>
<div id="content" style="visibility: hidden;">
<form id='f' method='get' target='submit_frame' action='foo'>
<meter id='m' value=0.5></meter>
</form>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 657938 **/
function checkFormIDLAttribute(aElement)
{
var form = document.forms[0];
var content = document.getElementById('content');
is(aElement.form, form, "The form IDL attribute should be the parent form");
content.removeChild(form);
content.appendChild(aElement);
is(aElement.form, null, "The form IDL attribute should be null");
// Cleaning-up.
content.appendChild(form);
form.appendChild(aElement);
}
function checkAttribute(aElement, aAttribute, aNewValue, aExpectedValueForIDL)
{
var expectedValueForIDL = aNewValue;
var expectedValueForContent = aNewValue;
if (aExpectedValueForIDL !== undefined) {
expectedValueForIDL = aExpectedValueForIDL;
}
if (aNewValue != null) {
aElement.setAttribute(aAttribute, aNewValue);
is(aElement.getAttribute(aAttribute), expectedValueForContent,
aAttribute + " content attribute should be " + expectedValueForContent);
is(aElement[aAttribute], expectedValueForIDL,
aAttribute + " IDL attribute should be " + expectedValueForIDL);
if (parseFloat(aNewValue) == aNewValue) {
aElement[aAttribute] = aNewValue;
is(aElement.getAttribute(aAttribute), expectedValueForContent,
aAttribute + " content attribute should be " + expectedValueForContent);
is(aElement[aAttribute], parseFloat(expectedValueForIDL),
aAttribute + " IDL attribute should be " + parseFloat(expectedValueForIDL));
}
} else {
aElement.removeAttribute(aAttribute);
is(aElement.getAttribute(aAttribute), expectedValueForContent,
aAttribute + " content attribute should be " + expectedValueForContent);
is(aElement[aAttribute], expectedValueForIDL,
aAttribute + " IDL attribute should be " + expectedValueForIDL);
}
}
function checkValueAttribute()
{
var tests = [
// value has to be a valid float, its default value is 0.0 otherwise.
[ null, 0.0 ],
[ 'foo', 0.0 ],
// If value < 0.0, 0.0 is used instead.
[ -1.0, 0.0 ],
// If value >= max, max is used instead (max default value is 1.0).
[ 2.0, 1.0 ],
[ 1.0, 0.5, 0.5 ],
[ 10.0, 5.0, 5.0 ],
[ 13.37, 13.37, 42.0 ],
// If value <= min, min is used instead (min default value is 0.0).
[ 0.5, 1.0, 10.0 ,1.0 ],
[ 10.0, 13.37, 42.0 , 13.37],
// Regular reflection.
[ 0.0 ],
[ 0.5 ],
[ 1.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
if (test[2]) {
element.setAttribute('max', test[2]);
}
if (test[3]) {
element.setAttribute('min', test[3]);
}
checkAttribute(element, 'value', test[0], test[1]);
element.removeAttribute('max');
element.removeAttribute('min');
}
}
function checkMinAttribute()
{
var tests = [
// min default value is 0.0.
[ null, 0.0 ],
[ 'foo', 0.0 ],
// Regular reflection.
[ 0.5 ],
[ 1.0 ],
[ 2.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
checkAttribute(element, 'min', test[0], test[1]);
}
}
function checkMaxAttribute()
{
var tests = [
// max default value is 1.0.
[ null, 1.0 ],
[ 'foo', 1.0 ],
// If value <= min, min is used instead.
[ -1.0, 0.0 ],
[ 0.0, 0.5, 0.5 ],
[ 10.0, 15.0, 15.0 ],
[ 42, 42, 13.37 ],
// Regular reflection.
[ 0.5 ],
[ 1.0 ],
[ 2.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
if (test[2]) {
element.setAttribute('min', test[2]);
}
checkAttribute(element, 'max', test[0], test[1]);
element.removeAttribute('min');
}
}
function checkLowAttribute()
{
var tests = [
// low default value is min (min default value is 0.0).
[ null, 0.0 ],
[ 'foo', 0.0 ],
[ 'foo', 1.0, 1.0],
// If low <= min, min is used instead.
[ -1.0, 0.0 ],
[ 0.0, 0.5, 0.5 ],
[ 10.0, 15.0, 15.0, 42.0 ],
[ 42.0, 42.0, 13.37, 100.0 ],
// If low >= max, max is used instead.
[ 2.0, 1.0 ],
[ 10.0, 5.0 , 0.5, 5.0 ],
[ 13.37, 13.37, 0.0, 42.0 ],
// Regular reflection.
[ 0.0 ],
[ 0.5 ],
[ 1.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
if (test[2]) {
element.setAttribute('min', test[2]);
}
if (test[3]) {
element.setAttribute('max', test[3]);
}
checkAttribute(element, 'low', test[0], test[1]);
element.removeAttribute('min');
element.removeAttribute('max');
}
}
function checkHighAttribute()
{
var tests = [
// high default value is max (max default value is 1.0).
[ null, 1.0 ],
[ 'foo', 1.0 ],
[ 'foo', 42.0, 0.0, 42.0],
// If high <= min, min is used instead.
[ -1.0, 0.0 ],
[ 0.0, 0.5, 0.5 ],
[ 10.0, 15.0, 15.0, 42.0 ],
[ 42.0, 42.0, 13.37, 100.0 ],
// If high >= max, max is used instead.
[ 2.0, 1.0 ],
[ 10.0, 5.0 , 0.5, 5.0 ],
[ 13.37, 13.37, 0.0, 42.0 ],
// Regular reflection.
[ 0.0 ],
[ 0.5 ],
[ 1.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
if (test[2]) {
element.setAttribute('min', test[2]);
}
if (test[3]) {
element.setAttribute('max', test[3]);
}
checkAttribute(element, 'high', test[0], test[1]);
element.removeAttribute('min');
element.removeAttribute('max');
}
}
function checkOptimumAttribute()
{
var tests = [
// opt default value is (max-min)/2 (thus default value is 0.5).
[ null, 0.5 ],
[ 'foo', 0.5 ],
[ 'foo', 2.0, 1.0, 3.0],
// If opt <= min, min is used instead.
[ -1.0, 0.0 ],
[ 0.0, 0.5, 0.5 ],
[ 10.0, 15.0, 15.0, 42.0 ],
[ 42.0, 42.0, 13.37, 100.0 ],
// If opt >= max, max is used instead.
[ 2.0, 1.0 ],
[ 10.0, 5.0 , 0.5, 5.0 ],
[ 13.37, 13.37, 0.0, 42.0 ],
// Regular reflection.
[ 0.0 ],
[ 0.5 ],
[ 1.0 ],
// Check double-precision value.
[ 0.234567898765432 ],
];
var element = document.createElement('meter');
for each(var test in tests) {
if (test[2]) {
element.setAttribute('min', test[2]);
}
if (test[3]) {
element.setAttribute('max', test[3]);
}
checkAttribute(element, 'optimum', test[0], test[1]);
element.removeAttribute('min');
element.removeAttribute('max');
}
}
function checkFormListedElement(aElement)
{
is(document.forms[0].elements.length, 0, "the form should have no element");
}
function checkLabelable(aElement)
{
var content = document.getElementById('content');
var label = document.createElement('label');
content.appendChild(label);
label.appendChild(aElement);
is(label.control, aElement, "meter should be labelable");
// Cleaning-up.
content.removeChild(label);
content.appendChild(aElement);
}
function checkNotResetableAndFormSubmission(aElement)
{
// Creating an input element to check the submission worked.
var form = document.forms[0];
var input = document.createElement('input');
input.name = 'a';
input.value = 'tulip';
form.appendChild(input);
// Setting values.
aElement.value = 42.0;
aElement.max = 100.0;
document.getElementsByName('submit_frame')[0].addEventListener("load", function() {
document.getElementsByName('submit_frame')[0].removeEventListener("load", arguments.callee, false);
/**
* All elements values have been set just before the submission.
* The input element value should be in the submit url but the meter
* element value should not appear.
*/
is(frames['submit_frame'].location.href,
'http://mochi.test:8888/tests/content/html/content/test/foo?a=tulip',
"The meter element value should not be submitted");
checkNotResetable();
}, false);
form.submit();
}
function checkNotResetable()
{
// Try to reset the form.
var form = document.forms[0];
var element = document.getElementById('m');
element.value = 3.0;
element.max = 42.0;
form.reset();
SimpleTest.executeSoon(function() {
is(element.value, 3.0, "meter.value should not have changed");
is(element.max, 42.0, "meter.max should not have changed");
SimpleTest.finish();
});
}
SimpleTest.waitForExplicitFinish();
var m = document.getElementById('m');
ok(m instanceof HTMLMeterElement,
"The meter element should be instance of HTMLMeterElement");
is(m.constructor, HTMLMeterElement,
"The meter element constructor should be HTMLMeterElement");
checkFormIDLAttribute(m);
checkValueAttribute();
checkMinAttribute();
checkMaxAttribute();
checkLowAttribute();
checkHighAttribute();
checkOptimumAttribute();
checkFormListedElement(m);
checkLabelable(m);
checkNotResetableAndFormSubmission(m);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,170 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=660238
-->
<head>
<title>Test for Bug 660238</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<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=770238">Mozilla Bug 660238</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 660238 **/
function checkOptimum(aElement, aValue, aOptimum, expectedResult)
{
var errorString = "value attribute should be in the optimum region";
if (!expectedResult) {
errorString = "value attribute should not be in the optimum region";
}
aElement.setAttribute('value', aValue);
aElement.setAttribute('optimum', aOptimum);
is(aElement.mozMatchesSelector(":-moz-meter-optimum"),
expectedResult, errorString);
}
function checkSubOptimum(aElement, aValue, aOptimum, expectedResult)
{
var errorString = "value attribute should be in the suboptimal region";
if (!expectedResult) {
errorString = "value attribute should not be in the suboptimal region";
}
aElement.setAttribute('value', aValue);
aElement.setAttribute('optimum', aOptimum);
is(aElement.mozMatchesSelector(":-moz-meter-sub-optimum"),
expectedResult, errorString);
}
function checkSubSubOptimum(aElement, aValue, aOptimum, expectedResult)
{
var errorString = "value attribute should be in the sub-suboptimal region";
if (!expectedResult) {
errorString = "value attribute should not be in the sub-suboptimal region";
}
aElement.setAttribute('value', aValue);
aElement.setAttribute('optimum', aOptimum);
is(aElement.mozMatchesSelector(":-moz-meter-sub-sub-optimum"),
expectedResult, errorString);
}
function checkMozMatchesSelector()
{
var element = document.createElement('meter');
// all tests realised with default values for min and max (0 and 1)
// low = 0.3 and high = 0.7
element.setAttribute('low', 0.3);
element.setAttribute('high', 0.7);
var tests = [
/*
* optimum = 0.0 =>
* optimum region = [ 0.0, 0.3 [
* suboptimal region = [ 0.3, 0.7 ]
* sub-suboptimal region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.0, true, false, false ],
[ 0.1, 0.0, true, false, false ],
[ 0.3, 0.0, false, true, false ],
[ 0.5, 0.0, false, true, false ],
[ 0.7, 0.0, false, true, false ],
[ 0.8, 0.0, false, false, true ],
[ 1.0, 0.0, false, false, true ],
/*
* optimum = 0.1 =>
* optimum region = [ 0.0, 0.3 [
* suboptimal region = [ 0.3, 0.7 ]
* sub-suboptimal region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.1, true, false, false ],
[ 0.1, 0.1, true, false, false ],
[ 0.3, 0.1, false, true, false ],
[ 0.5, 0.1, false, true, false ],
[ 0.7, 0.1, false, true, false ],
[ 0.8, 0.1, false, false, true ],
[ 1.0, 0.1, false, false, true ],
/*
* optimum = 0.3 =>
* suboptimal region = [ 0.0, 0.3 [
* optimum region = [ 0.3, 0.7 ]
* suboptimal region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.3, false, true, false ],
[ 0.1, 0.3, false, true, false ],
[ 0.3, 0.3, true, false, false ],
[ 0.5, 0.3, true, false, false ],
[ 0.7, 0.3, true, false, false ],
[ 0.8, 0.3, false, true, false ],
[ 1.0, 0.3, false, true, false ],
/*
* optimum = 0.5 =>
* suboptimal region = [ 0.0, 0.3 [
* optimum region = [ 0.3, 0.7 ]
* suboptimal region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.5, false, true, false ],
[ 0.1, 0.5, false, true, false ],
[ 0.3, 0.5, true, false, false ],
[ 0.5, 0.5, true, false, false ],
[ 0.7, 0.5, true, false, false ],
[ 0.8, 0.5, false, true, false ],
[ 1.0, 0.5, false, true, false ],
/*
* optimum = 0.7 =>
* suboptimal region = [ 0.0, 0.3 [
* optimum region = [ 0.3, 0.7 ]
* suboptimal region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.7, false, true, false ],
[ 0.1, 0.7, false, true, false ],
[ 0.3, 0.7, true, false, false ],
[ 0.5, 0.7, true, false, false ],
[ 0.7, 0.7, true, false, false ],
[ 0.8, 0.7, false, true, false ],
[ 1.0, 0.7, false, true, false ],
/*
* optimum = 0.8 =>
* sub-suboptimal region = [ 0.0, 0.3 [
* suboptimal region = [ 0.3, 0.7 ]
* optimum region = ] 0.7, 1.0 ]
*/
[ 0.0, 0.8, false, false, true ],
[ 0.1, 0.8, false, false, true ],
[ 0.3, 0.8, false, true, false ],
[ 0.5, 0.8, false, true, false ],
[ 0.7, 0.8, false, true, false ],
[ 0.8, 0.8, true, false, false ],
[ 1.0, 0.8, true, false, false ],
/*
* optimum = 1.0 =>
* sub-suboptimal region = [ 0.0, 0.3 [
* suboptimal region = [ 0.3, 0.7 ]
* optimum region = ] 0.7, 1.0 ]
*/
[ 0.0, 1.0, false, false, true ],
[ 0.1, 1.0, false, false, true ],
[ 0.3, 1.0, false, true, false ],
[ 0.5, 1.0, false, true, false ],
[ 0.7, 1.0, false, true, false ],
[ 0.8, 1.0, true, false, false ],
[ 1.0, 1.0, true, false, false ],
];
for each(var test in tests) {
checkOptimum(element, test[0], test[1], test[2]);
checkSubOptimum(element, test[0], test[1], test[3]);
checkSubSubOptimum(element, test[0], test[1], test[4]);
}
}
checkMozMatchesSelector();
</script>
</pre>
</body>
</html>

View File

@ -248,6 +248,7 @@
#include "nsIDOMHTMLMenuElement.h"
#include "nsIDOMHTMLMenuItemElement.h"
#include "nsIDOMHTMLMetaElement.h"
#include "nsIDOMHTMLMeterElement.h"
#include "nsIDOMHTMLModElement.h"
#include "nsIDOMHTMLOListElement.h"
#include "nsIDOMHTMLObjectElement.h"
@ -905,6 +906,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLMetaElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLMeterElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLModElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLOListElement, nsElementSH,
@ -2918,6 +2921,11 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(HTMLMeterElement, nsIDOMHTMLMeterElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLMeterElement)
DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(HTMLModElement, nsIDOMHTMLModElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLModElement)
DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES

View File

@ -95,6 +95,7 @@ DOMCI_CLASS(HTMLMapElement)
DOMCI_CLASS(HTMLMenuElement)
DOMCI_CLASS(HTMLMenuItemElement)
DOMCI_CLASS(HTMLMetaElement)
DOMCI_CLASS(HTMLMeterElement)
DOMCI_CLASS(HTMLModElement)
DOMCI_CLASS(HTMLOListElement)
DOMCI_CLASS(HTMLObjectElement)

View File

@ -51,6 +51,7 @@ SDK_XPIDLSRCS = \
nsIDOMHTMLMenuElement.idl \
nsIDOMHTMLMenuItemElement.idl \
nsIDOMHTMLMetaElement.idl \
nsIDOMHTMLMeterElement.idl \
nsIDOMHTMLModElement.idl \
nsIDOMHTMLOListElement.idl \
nsIDOMHTMLObjectElement.idl \

View File

@ -0,0 +1,64 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
* Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
* Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLElement.idl"
/**
* The nsIDOMHTMLMeterElement interface is the interface to a HTML
* <meter> element.
*
* For more information on this interface, please see
* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-meter-element
*/
[scriptable, uuid(d4466510-8143-11e0-b278-0800200c9a66)]
interface nsIDOMHTMLMeterElement : nsIDOMHTMLElement
{
attribute double value;
attribute double min;
attribute double max;
attribute double low;
attribute double high;
attribute double optimum;
readonly attribute nsIDOMHTMLFormElement form;
/**
* The labels attribute will be done with bug 556743.
*/
//readonly attribute NodeList labels;
};

View File

@ -114,6 +114,7 @@ EDITOR_ATOM(legend, "legend")
EDITOR_ATOM(li, "li")
EDITOR_ATOM(map, "map")
EDITOR_ATOM(mark, "mark")
EDITOR_ATOM(meter, "meter")
EDITOR_ATOM(menuitem, "menuitem")
EDITOR_ATOM(mozdirty, "_moz_dirty")
EDITOR_ATOM(mozEditorBogusNode, "_moz_editor_bogus_node")

View File

@ -466,6 +466,7 @@ nsHTMLEditUtils::IsFormWidget(dom::Element* node)
|| (nodeAtom == nsEditProperty::output)
|| (nodeAtom == nsEditProperty::keygen)
|| (nodeAtom == nsEditProperty::progress)
|| (nodeAtom == nsEditProperty::meter)
|| (nodeAtom == nsEditProperty::input);
}
@ -517,7 +518,7 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDOMNode * aNode)
// strong, var
#define GROUP_PHRASE (1 << 4)
// a, applet, basefont, bdo, br, font, iframe, img, map, object, output,
// a, applet, basefont, bdo, br, font, iframe, img, map, meter, object, output,
// progress, q, script, span, sub, sup
#define GROUP_SPECIAL (1 << 5)
@ -695,6 +696,7 @@ static const nsElementInfo kElements[eHTMLTag_userdefined] = {
ELEM(menu, true, true, GROUP_BLOCK, GROUP_LI | GROUP_FLOW_ELEMENT),
ELEM(menuitem, false, false, GROUP_NONE, GROUP_NONE),
ELEM(meta, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
ELEM(meter, true, false, GROUP_SPECIAL, GROUP_FLOW_ELEMENT),
ELEM(multicol, false, false, GROUP_NONE, GROUP_NONE),
ELEM(nav, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
ELEM(nobr, false, false, GROUP_NONE, GROUP_NONE),

View File

@ -103,6 +103,12 @@
// A vertical progress chunk
#define NS_THEME_PROGRESSBAR_CHUNK_VERTICAL 54
// A horizontal meter bar.
#define NS_THEME_METERBAR 55
// The meter bar's meter indicator
#define NS_THEME_METERBAR_CHUNK 56
// A single tab in a tab widget.
#define NS_THEME_TAB 61

View File

@ -282,6 +282,7 @@ members = [
'nsIDOMHTMLInputElement.selectionDirection',
'nsIDOMHTMLInputElement.setSelectionRange',
'nsIDOMHTMLLinkElement.disabled',
'nsIDOMHTMLMeterElement.*',
'nsIDOMHTMLMenuElement.*',
'nsIDOMHTMLMenuItemElement.*',
'nsIDOMHTMLOptionElement.index',

View File

@ -3380,7 +3380,8 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
SIMPLE_TAG_CREATE(video, NS_NewHTMLVideoFrame),
SIMPLE_TAG_CREATE(audio, NS_NewHTMLVideoFrame),
#endif
SIMPLE_TAG_CREATE(progress, NS_NewProgressFrame)
SIMPLE_TAG_CREATE(progress, NS_NewProgressFrame),
SIMPLE_TAG_CREATE(meter, NS_NewMeterFrame)
};
return FindDataByTag(aTag, aElement, aStyleContext, sHTMLData,

View File

@ -39,6 +39,7 @@ CPPSRCS = \
nsGfxCheckboxControlFrame.cpp \
nsGfxRadioControlFrame.cpp \
nsProgressFrame.cpp \
nsMeterFrame.cpp \
nsTextControlFrame.cpp \
nsHTMLButtonControlFrame.cpp \
nsImageControlFrame.cpp \

View File

@ -0,0 +1,314 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mounir Lamouri <mounir.lamouri@mozilla.com>
* Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
* Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
* Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMeterFrame.h"
#include "nsIDOMHTMLMeterElement.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsPresContext.h"
#include "nsGkAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsNodeInfoManager.h"
#include "nsINodeInfo.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "nsFormControlFrame.h"
#include "nsFontMetrics.h"
#include "mozilla/dom/Element.h"
nsIFrame*
NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsMeterFrame(aContext);
}
NS_IMPL_FRAMEARENA_HELPERS(nsMeterFrame)
nsMeterFrame::nsMeterFrame(nsStyleContext* aContext)
: nsContainerFrame(aContext)
, mBarDiv(nsnull)
{
}
nsMeterFrame::~nsMeterFrame()
{
}
void
nsMeterFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
NS_ASSERTION(!GetPrevContinuation(),
"nsMeterFrame should not have continuations; if it does we "
"need to call RegUnregAccessKey only for the first.");
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
nsContentUtils::DestroyAnonymousContent(&mBarDiv);
nsContainerFrame::DestroyFrom(aDestructRoot);
}
nsresult
nsMeterFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
// Get the NodeInfoManager and tag necessary to create the meter bar div.
nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
nsCOMPtr<nsINodeInfo> nodeInfo;
nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
// Create the div.
nsresult rv = NS_NewHTMLElement(getter_AddRefs(mBarDiv), nodeInfo.forget(),
mozilla::dom::NOT_FROM_PARSER);
NS_ENSURE_SUCCESS(rv, rv);
// Associate ::-moz-meter-bar pseudo-element to the anonymous child.
nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozMeterBar;
nsRefPtr<nsStyleContext> newStyleContext = PresContext()->StyleSet()->
ResolvePseudoElementStyle(mContent->AsElement(), pseudoType,
GetStyleContext());
if (!aElements.AppendElement(ContentInfo(mBarDiv, newStyleContext))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
void
nsMeterFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
PRUint32 aFilter)
{
aElements.MaybeAppendElement(mBarDiv);
}
NS_QUERYFRAME_HEAD(nsMeterFrame)
NS_QUERYFRAME_ENTRY(nsMeterFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
NS_IMETHODIMP nsMeterFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
DO_GLOBAL_REFLOW_COUNT("nsMeterFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
NS_ASSERTION(mBarDiv, "Meter bar div must exist!");
NS_ASSERTION(!GetPrevContinuation(),
"nsMeterFrame should not have continuations; if it does we "
"need to call RegUnregAccessKey only for the first.");
if (mState & NS_FRAME_FIRST_REFLOW) {
nsFormControlFrame::RegUnRegAccessKey(this, true);
}
nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
NS_ASSERTION(barFrame, "The meter frame should have a child with a frame!");
ReflowBarFrame(barFrame, aPresContext, aReflowState, aStatus);
aDesiredSize.width = aReflowState.ComputedWidth() +
aReflowState.mComputedBorderPadding.LeftRight();
aDesiredSize.height = aReflowState.ComputedHeight() +
aReflowState.mComputedBorderPadding.TopBottom();
aDesiredSize.height = NS_CSS_MINMAX(aDesiredSize.height,
aReflowState.mComputedMinHeight,
aReflowState.mComputedMaxHeight);
aDesiredSize.SetOverflowAreasToDesiredBounds();
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, barFrame);
FinishAndStoreOverflow(&aDesiredSize);
aStatus = NS_FRAME_COMPLETE;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
void
nsMeterFrame::ReflowBarFrame(nsIFrame* aBarFrame,
nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
bool vertical = GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
nsHTMLReflowState reflowState(aPresContext, aReflowState, aBarFrame,
nsSize(aReflowState.ComputedWidth(),
NS_UNCONSTRAINEDSIZE));
nscoord size = vertical ? aReflowState.ComputedHeight()
: aReflowState.ComputedWidth();
nscoord xoffset = aReflowState.mComputedBorderPadding.left;
nscoord yoffset = aReflowState.mComputedBorderPadding.top;
// NOTE: Introduce a new function getPosition in the content part ?
double position, max, min, value;
nsCOMPtr<nsIDOMHTMLMeterElement> meterElement =
do_QueryInterface(mContent);
meterElement->GetMax(&max);
meterElement->GetMin(&min);
meterElement->GetValue(&value);
position = max - min;
position = position != 0 ? (value - min) / position : 1;
size = NSToCoordRound(size * position);
if (!vertical && GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
xoffset += aReflowState.ComputedWidth() - size;
}
// The bar position is *always* constrained.
if (vertical) {
// We want the bar to begin at the bottom.
yoffset += aReflowState.ComputedHeight() - size;
size -= reflowState.mComputedMargin.TopBottom() +
reflowState.mComputedBorderPadding.TopBottom();
size = NS_MAX(size, 0);
reflowState.SetComputedHeight(size);
} else {
size -= reflowState.mComputedMargin.LeftRight() +
reflowState.mComputedBorderPadding.LeftRight();
size = NS_MAX(size, 0);
reflowState.SetComputedWidth(size);
}
xoffset += reflowState.mComputedMargin.left;
yoffset += reflowState.mComputedMargin.top;
nsHTMLReflowMetrics barDesiredSize;
ReflowChild(aBarFrame, aPresContext, barDesiredSize, reflowState, xoffset,
yoffset, 0, aStatus);
FinishReflowChild(aBarFrame, aPresContext, &reflowState, barDesiredSize,
xoffset, yoffset, 0);
}
NS_IMETHODIMP
nsMeterFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType)
{
NS_ASSERTION(mBarDiv, "Meter bar div must exist!");
if (aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::value ||
aAttribute == nsGkAtoms::max ||
aAttribute == nsGkAtoms::min )) {
nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
NS_ASSERTION(barFrame, "The meter frame should have a child with a frame!");
PresContext()->PresShell()->FrameNeedsReflow(barFrame,
nsIPresShell::eResize,
NS_FRAME_IS_DIRTY);
Invalidate(GetVisualOverflowRectRelativeToSelf());
}
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
aModType);
}
nsSize
nsMeterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
nsSize aCBSize, nscoord aAvailableWidth,
nsSize aMargin, nsSize aBorder,
nsSize aPadding, bool aShrinkWrap)
{
nsRefPtr<nsFontMetrics> fontMet;
NS_ENSURE_SUCCESS(nsLayoutUtils::GetFontMetricsForFrame(this,
getter_AddRefs(fontMet)),
nsSize(0, 0));
nsSize autoSize;
autoSize.height = autoSize.width = fontMet->Font().size; // 1em
if (GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
autoSize.height *= 5; // 5em
} else {
autoSize.width *= 5; // 5em
}
return autoSize;
}
nscoord
nsMeterFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
{
nsRefPtr<nsFontMetrics> fontMet;
NS_ENSURE_SUCCESS(
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
nscoord minWidth = fontMet->Font().size; // 1em
if (GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
minWidth *= 5; // 5em
}
return minWidth;
}
nscoord
nsMeterFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
{
return GetMinWidth(aRenderingContext);
}
bool
nsMeterFrame::ShouldUseNativeStyle() const
{
// Use the native style if these conditions are satisfied:
// - both frames use the native appearance;
// - neither frame has author specified rules setting the border or the
// background.
return GetStyleDisplay()->mAppearance == NS_THEME_METERBAR &&
mBarDiv->GetPrimaryFrame()->GetStyleDisplay()->mAppearance == NS_THEME_METERBAR_CHUNK &&
!PresContext()->HasAuthorSpecifiedRules(const_cast<nsMeterFrame*>(this),
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
!PresContext()->HasAuthorSpecifiedRules(mBarDiv->GetPrimaryFrame(),
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
}

115
layout/forms/nsMeterFrame.h Normal file
View File

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
* Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
* Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMeterFrame_h___
#define nsMeterFrame_h___
#include "nsContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsCOMPtr.h"
class nsMeterFrame : public nsContainerFrame,
public nsIAnonymousContentCreator
{
public:
NS_DECL_QUERYFRAME_TARGET(nsMeterFrame)
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
nsMeterFrame(nsStyleContext* aContext);
virtual ~nsMeterFrame();
virtual void DestroyFrom(nsIFrame* aDestructRoot);
NS_IMETHOD Reflow(nsPresContext* aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const {
return MakeFrameName(NS_LITERAL_STRING("Meter"), aResult);
}
#endif
virtual bool IsLeaf() const { return true; }
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
PRUint32 aFilter);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType);
virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
nsSize aCBSize, nscoord aAvailableWidth,
nsSize aMargin, nsSize aBorder,
nsSize aPadding, bool aShrinkWrap);
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
virtual bool IsFrameOfType(PRUint32 aFlags) const
{
return nsContainerFrame::IsFrameOfType(aFlags &
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
}
/**
* Returns whether the frame and its child should use the native style.
*/
bool ShouldUseNativeStyle() const;
protected:
// Helper function which reflow the anonymous div frame.
void ReflowBarFrame(nsIFrame* aBarFrame,
nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/**
* The div used to show the meter bar.
* @see nsMeterFrame::CreateAnonymousContent
*/
nsCOMPtr<nsIContent> mBarDiv;
};
#endif

View File

@ -187,6 +187,8 @@ nsIFrame*
NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags);
nsIFrame*
NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
// Table frame factories
nsIFrame*

View File

@ -141,6 +141,7 @@ public:
nsMenuBarFrame_id,
nsMenuFrame_id,
nsMenuPopupFrame_id,
nsMeterFrame_id,
nsObjectFrame_id,
nsPageBreakFrame_id,
nsPageContentFrame_id,

View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) > .meter-bar { margin: 10px; padding: 0px; }
body > div:nth-child(2) > .meter-bar { margin: 0px; padding: 10px; }
body > div:nth-child(3) > .meter-bar { margin: 10px; padding: 10px; }
body > div:nth-child(4) > .meter-bar { margin: 5px; padding: 5px; }
body > div:nth-child(5) > .meter-bar { margin: 50px; padding: 50px; }
body > div:nth-child(6) > .meter-bar { margin: 100px; padding: 100px; }
body > div:nth-child(7) > .meter-bar { margin: 10px 0px 0px 0px; padding: 0px; }
body > div:nth-child(8) > .meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(9) > .meter-bar { margin: 0px 0px 10px 0px; padding: 0px; }
body > div:nth-child(10) > .meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(11) > .meter-bar { margin: 0px; padding: 10px 0px 0px 0px; }
body > div:nth-child(12) > .meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(13) > .meter-bar { margin: 0px; padding: 0px 0px 10px 0px; }
body > div:nth-child(14) > .meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
body > div:nth-child(15) > .meter-bar { margin: 200px; padding: 0px; }
body > div:nth-child(16) > .meter-bar { margin: 0px; padding: 200px; }
/* 15 - 18 should have 100% width, no need to specify. */
</style>
<body>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) > .meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(2) > .meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(3) > .meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(4) > .meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
/* 15 - 18 should have 100% width, no need to specify. */
</style>
<body dir='rtl'>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > meter:nth-child(1)::-moz-meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > meter:nth-child(2)::-moz-meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > meter:nth-child(3)::-moz-meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > meter:nth-child(4)::-moz-meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
body > meter:nth-child(5)::-moz-meter-bar { width: 1000px; }
body > meter:nth-child(6)::-moz-meter-bar { width: 10px; }
body > meter:nth-child(7)::-moz-meter-bar { width: 10%; }
body > meter:nth-child(8)::-moz-meter-bar { width: 200%; }
</style>
<body dir='rtl'>
<!-- Those will be used to change padding/margin on ::-moz-meter-bar -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<!-- Those will be used to change width. -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
.meter-element { margin: 10px; }
body > div:nth-child(1) > .meter-bar { position: relative; top: 4px; left: 4px;
height: -moz-calc(100% - 8px); }
body > div:nth-child(2) > .meter-bar { width: -moz-calc(100% + 8px); }
body > div:nth-child(3) > .meter-bar { position: relative; top: 4px; left: 4px;
height: -moz-calc(100% - 8px);
width: -moz-calc(100% + 8px); }
body > div:nth-child(4) > .meter-bar { position: relative; top: 10px; height: -moz-calc(100% - 10px); }
body > div:nth-child(5) > .meter-bar { }
body > div:nth-child(6) > .meter-bar { height: -moz-calc(100% - 10px); }
body > div:nth-child(7) > .meter-bar { position: relative; left: 10px; }
body > div:nth-child(8) > .meter-bar { }
body > div:nth-child(9) > .meter-bar { width: -moz-calc(100% + 10px); }
body > div:nth-child(10) > .meter-bar { }
body > div:nth-child(11) > .meter-bar { width: -moz-calc(100% + 10px); }
/* 12 - 15 should have 100% width, no need to specify. */
body > div:nth-child(16) > .meter-bar { position: relative; top: 64px; left: 64px;
height: -moz-calc(100% + 32px + 16px);
width: -moz-calc(100% + 128px + 16px - 1em); }
</style>
<body>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
.meter-element { margin: 10px; }
body > div:nth-child(1) > .meter-bar { position: relative; top: 4px; left: 4px;
height: -moz-calc(100% - 8px); }
body > div:nth-child(2) > .meter-bar { position: relative; left: 8px;
width: -moz-calc(100% + 8px); }
body > div:nth-child(3) > .meter-bar { position: relative; top: 4px; left: 12px;
height: -moz-calc(100% - 8px);
width: -moz-calc(100% + 8px); }
body > div:nth-child(4) > .meter-bar { position: relative; top: 10px; height: -moz-calc(100% - 10px); }
body > div:nth-child(5) > .meter-bar { }
body > div:nth-child(6) > .meter-bar { height: -moz-calc(100% - 10px); }
body > div:nth-child(7) > .meter-bar { position: relative; left: 10px; }
body > div:nth-child(8) > .meter-bar { }
body > div:nth-child(9) > .meter-bar { position: relative; left: 10px;
width: -moz-calc(100% + 10px); }
body > div:nth-child(10) > .meter-bar { }
body > div:nth-child(11) > .meter-bar { position: relative; left: 10px;
width: -moz-calc(100% + 10px); }
/* 12 - 15 should have 100% width, no need to specify. */
body > div:nth-child(16) > .meter-bar { position: relative; top: 64px; left: 192px;
height: -moz-calc(100% + 64px - 1em);
width: -moz-calc(100% + 128px); }
</style>
<body dir='rtl'>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
margin: 10px;
-moz-orient: vertical;
}
body > meter:nth-child(1)::-moz-meter-bar { margin: 4px; padding: 0px; }
body > meter:nth-child(2)::-moz-meter-bar { margin: 0px; padding: 4px; }
body > meter:nth-child(3)::-moz-meter-bar { margin: 4px; padding: 4px; }
body > meter:nth-child(4)::-moz-meter-bar { margin: 10px 0px 0px 0px; padding: 0px; }
body > meter:nth-child(5)::-moz-meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > meter:nth-child(6)::-moz-meter-bar { margin: 0px 0px 10px 0px; padding: 0px; }
body > meter:nth-child(7)::-moz-meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > meter:nth-child(8)::-moz-meter-bar { margin: 0px; padding: 10px 0px 0px 0px; }
body > meter:nth-child(9)::-moz-meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > meter:nth-child(10)::-moz-meter-bar { margin: 0px; padding: 0px 0px 10px 0px; }
body > meter:nth-child(11)::-moz-meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
body > meter:nth-child(12)::-moz-meter-bar { height: 1000px; }
body > meter:nth-child(13)::-moz-meter-bar { height: 10px; }
body > meter:nth-child(14)::-moz-meter-bar { height: 10%; }
body > meter:nth-child(15)::-moz-meter-bar { height: 200%; }
body > meter:nth-child(16)::-moz-meter-bar { margin: 64px; padding: 64px; }
</style>
<body dir='rtl'>
<!-- Those will be used to change padding/margin on ::-moz-meter-bar -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<!-- Those will be used to change width. -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
margin: 10px;
-moz-orient: vertical;
}
body > meter:nth-child(1)::-moz-meter-bar { margin: 4px; padding: 0px; }
body > meter:nth-child(2)::-moz-meter-bar { margin: 0px; padding: 4px; }
body > meter:nth-child(3)::-moz-meter-bar { margin: 4px; padding: 4px; }
body > meter:nth-child(4)::-moz-meter-bar { margin: 10px 0px 0px 0px; padding: 0px; }
body > meter:nth-child(5)::-moz-meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > meter:nth-child(6)::-moz-meter-bar { margin: 0px 0px 10px 0px; padding: 0px; }
body > meter:nth-child(7)::-moz-meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > meter:nth-child(8)::-moz-meter-bar { margin: 0px; padding: 10px 0px 0px 0px; }
body > meter:nth-child(9)::-moz-meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > meter:nth-child(10)::-moz-meter-bar { margin: 0px; padding: 0px 0px 10px 0px; }
body > meter:nth-child(11)::-moz-meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
body > meter:nth-child(12)::-moz-meter-bar { height: 1000px; }
body > meter:nth-child(13)::-moz-meter-bar { height: 10px; }
body > meter:nth-child(14)::-moz-meter-bar { height: 10%; }
body > meter:nth-child(15)::-moz-meter-bar { height: 200%; }
body > meter:nth-child(16)::-moz-meter-bar { margin: 64px; padding: 64px; }
</style>
<body>
<!-- Those will be used to change padding/margin on ::-moz-meter-bar -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<!-- Those will be used to change width. -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > meter:nth-child(1)::-moz-meter-bar { margin: 10px; padding: 0px; }
body > meter:nth-child(2)::-moz-meter-bar { margin: 0px; padding: 10px; }
body > meter:nth-child(3)::-moz-meter-bar { margin: 10px; padding: 10px; }
body > meter:nth-child(4)::-moz-meter-bar { margin: 5px; padding: 5px; }
body > meter:nth-child(5)::-moz-meter-bar { margin: 50px; padding: 50px; }
body > meter:nth-child(6)::-moz-meter-bar { margin: 100px; padding: 100px; }
body > meter:nth-child(7)::-moz-meter-bar { margin: 10px 0px 0px 0px; padding: 0px; }
body > meter:nth-child(8)::-moz-meter-bar { margin: 0px 10px 0px 0px; padding: 0px; }
body > meter:nth-child(9)::-moz-meter-bar { margin: 0px 0px 10px 0px; padding: 0px; }
body > meter:nth-child(10)::-moz-meter-bar { margin: 0px 0px 0px 10px; padding: 0px; }
body > meter:nth-child(11)::-moz-meter-bar { margin: 0px; padding: 10px 0px 0px 0px; }
body > meter:nth-child(12)::-moz-meter-bar { margin: 0px; padding: 0px 10px 0px 0px; }
body > meter:nth-child(13)::-moz-meter-bar { margin: 0px; padding: 0px 0px 10px 0px; }
body > meter:nth-child(14)::-moz-meter-bar { margin: 0px; padding: 0px 0px 0px 10px; }
body > meter:nth-child(15)::-moz-meter-bar { margin: 200px; padding: 0px; }
body > meter:nth-child(16)::-moz-meter-bar { margin: 0px; padding: 200px; }
body > meter:nth-child(17)::-moz-meter-bar { width: 1000px; }
body > meter:nth-child(18)::-moz-meter-bar { width: 10px; }
body > meter:nth-child(19)::-moz-meter-bar { width: 10%; }
body > meter:nth-child(20)::-moz-meter-bar { width: 200%; }
</style>
<body>
<!-- Those will be used to change padding/margin on ::-moz-meter-bar -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<!-- Those will be used to change width. -->
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter { display: block; }
</style>
<body>
<meter value='0.5'></meter>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html class='reftest-wait'>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter { display: block; }
</style>
<script>
function loadHandler() {
setTimeout(function() {
var p = document.getElementsByTagName('meter')[0];
p.value = '0.5';
document.documentElement.className = '';
}, 0);
}
</script>
<body onload="loadHandler();">
<meter value='0'></meter>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
div:nth-child(1) > .meter-sub-optimum { width: 10%; }
div:nth-child(2) > .meter-sub-sub-optimum { width: 10%; }
div:nth-child(3) > .meter-sub-optimum { width: 40%; }
div:nth-child(4) > .meter-optimum { width: 10%; }
div:nth-child(5) > .meter-optimum { width: 0%; }
div:nth-child(6) > .meter-sub-optimum { width: 20%; }
</style>
<body>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<body>
<meter id='m1' value="0.1" low="0" optimum="0.5" high="1" min="0" max="1"></meter>
<meter id='m2' value="0.1" low="0.3" optimum="0.7" high="1" min="0" max="1"></meter>
<meter id='m3' value="0.1" low="0.3" optimum="0.7" high="0.5" min="0" max="1"></meter>
<meter id='m4' value="0.1" low="0.3" optimum="0.7" high="0.5" min="0" max="1"></meter>
<meter id='m5' value="0.1" low="0.3" optimum="0.7" high="0.5" min="0" max="1"></meter>
<meter id='m6' value="0.1" low="0.3" optimum="0.7" high="0.5" min="0" max="1"></meter>
<script>
var m = document.getElementById('m1');
m.setAttribute("low",0.3);
m = document.getElementById('m2');
m.setAttribute("high",0.5);
m = document.getElementById('m3');
m.setAttribute("value",0.4);
m = document.getElementById('m4');
m.setAttribute("optimum",0.1);
m = document.getElementById('m5');
m.setAttribute("min",0.9);
m = document.getElementById('m6');
m.setAttribute("max",0.5);
</script>
</body>
</html>

View File

@ -0,0 +1,279 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
/* optimum = 0.0 */
div:nth-child(1) > .meter-optimum { width: 0%; }
div:nth-child(2) > .meter-optimum { width: 10%; }
div:nth-child(3) > .meter-sub-optimum { width: 30%; }
div:nth-child(4) > .meter-sub-optimum { width: 50%; }
div:nth-child(5) > .meter-sub-optimum { width: 70%; }
div:nth-child(6) > .meter-sub-sub-optimum { width: 80%; }
div:nth-child(7) > .meter-sub-sub-optimum { width: 100%; }
/* optimum = 0.1 */
div:nth-child(8) > .meter-optimum { width: 0%; }
div:nth-child(9) > .meter-optimum { width: 10%; }
div:nth-child(10) > .meter-sub-optimum { width: 30%; }
div:nth-child(11) > .meter-sub-optimum { width: 50%; }
div:nth-child(12) > .meter-sub-optimum { width: 70%; }
div:nth-child(13) > .meter-sub-sub-optimum { width: 80%; }
div:nth-child(14) > .meter-sub-sub-optimum { width: 100%; }
/* optimum = 0.3 */
div:nth-child(15) > .meter-sub-optimum { width: 0%; }
div:nth-child(16) > .meter-sub-optimum { width: 10%; }
div:nth-child(17) > .meter-optimum { width: 30%; }
div:nth-child(18) > .meter-optimum { width: 50%; }
div:nth-child(19) > .meter-optimum { width: 70%; }
div:nth-child(20) > .meter-sub-optimum { width: 80%; }
div:nth-child(21) > .meter-sub-optimum { width: 100%; }
/* optimum = 0.5 */
div:nth-child(22) > .meter-sub-optimum { width: 0%; }
div:nth-child(23) > .meter-sub-optimum { width: 10%; }
div:nth-child(24) > .meter-optimum { width: 30%; }
div:nth-child(25) > .meter-optimum { width: 50%; }
div:nth-child(26) > .meter-optimum { width: 70%; }
div:nth-child(27) > .meter-sub-optimum { width: 80%; }
div:nth-child(28) > .meter-sub-optimum { width: 100%; }
/* optimum = 0.7 */
div:nth-child(29) > .meter-sub-optimum { width: 0%; }
div:nth-child(30) > .meter-sub-optimum { width: 10%; }
div:nth-child(31) > .meter-optimum { width: 30%; }
div:nth-child(32) > .meter-optimum { width: 50%; }
div:nth-child(33) > .meter-optimum { width: 70%; }
div:nth-child(34) > .meter-sub-optimum { width: 80%; }
div:nth-child(35) > .meter-sub-optimum { width: 100%; }
/* optimum = 0.8 */
div:nth-child(36) > .meter-sub-sub-optimum { width: 0%; }
div:nth-child(37) > .meter-sub-sub-optimum { width: 10%; }
div:nth-child(38) > .meter-sub-optimum { width: 30%; }
div:nth-child(39) > .meter-sub-optimum { width: 50%; }
div:nth-child(40) > .meter-sub-optimum { width: 70%; }
div:nth-child(41) > .meter-optimum { width: 80%; }
div:nth-child(42) > .meter-optimum { width: 100%; }
/* optimum = 1.0 */
div:nth-child(43) > .meter-sub-sub-optimum { width: 0%; }
div:nth-child(44) > .meter-sub-sub-optimum { width: 10%; }
div:nth-child(45) > .meter-sub-optimum { width: 30%; }
div:nth-child(46) > .meter-sub-optimum { width: 50%; }
div:nth-child(47) > .meter-sub-optimum { width: 70%; }
div:nth-child(48) > .meter-optimum { width: 80%; }
div:nth-child(49) > .meter-optimum { width: 100%; }
</style>
<body>
<!-- optimum = 0.0 -->
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<!-- optimum = 0.1 -->
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<!-- optimum = 0.3 -->
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<!-- optimum = 0.5 -->
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<!-- optimum = 0.7 -->
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<!-- optimum = 0.8 -->
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<!-- optimum = 1.0 -->
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-sub-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
<div class="meter-element">
<div class="meter-optimum">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<body>
<meter value="0.0" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.0" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.1" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.3" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.5" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.7" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="0.8" high="0.7"></meter>
<meter value="0.0" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="0.1" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="0.3" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="0.5" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="0.7" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="0.8" low="0.3" optimum="1.0" high="0.7"></meter>
<meter value="1.0" low="0.3" optimum="1.0" high="0.7"></meter>
</body>
</html>

View File

@ -0,0 +1,2 @@
== default-style.html default-style-ref.html
== default-style-dyn.html default-style-dyn-ref.html

View File

@ -0,0 +1,54 @@
div.meter-element {
display: inline-block;
height: 1em;
width: 5em;
vertical-align: -0.2em;
background: -moz-linear-gradient(top, #e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
}
div.meter-optimum {
float: none ! important;
height: 100%;
/*
* We can't apply the following style to the reference because it will have
* underisable effectes:
* width: 100%;
*/
/* green. */
background: -moz-linear-gradient(top, #ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
}
div.meter-sub-optimum {
float: none ! important;
height: 100%;
/*
* We can't apply the following style to the reference because it will have
* underisable effectes:
* width: 100%;
*/
/* orange. */
background: -moz-linear-gradient(top, #fe7, #fe7, #ffc 20%, #db3 45%, #db3 55%);
}
div.meter-sub-sub-optimum {
float: none ! important;
height: 100%;
/*
* We can't apply the following style to the reference because it will have
* underisable effectes:
* width: 100%;
*/
/* red. */
background: -moz-linear-gradient(top, #f77, #f77, #fcc 20%, #d44 45%, #d44 55%);
}
meter, meter::-moz-meter-bar, div.meter-element, div.meter-optimum, div.meter-sub-optimum, div.meter-sub-sub-optimum {
-moz-appearance: none;
}

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter { width: 5em; height: 1em; }
meter.vertical { -moz-orient: vertical; width: 1em; height: 5em; }
</style>
<body>
<table>
<tr>
<td>foo</td>
<td><meter value='0.5'></meter></td>
<td>bar</td>
</tr>
<tr>
<td>foo</td>
<td><meter class='vertical' value='0.5'></meter></td>
<td>bar</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter.vertical { -moz-orient: vertical; }
</style>
<body>
<table>
<tr>
<td>foo</td>
<td><meter value='0.5'></meter></td>
<td>bar</td>
</tr>
<tr>
<td>foo</td>
<td><meter class='vertical' value='0.5'></meter></td>
<td>bar</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) { margin: 10px; padding: 0px; }
body > div:nth-child(2) { margin: 0px; padding: 10px; }
body > div:nth-child(3) { margin: 10px; padding: 10px; }
body > div:nth-child(4) { margin: 5px; padding: 5px; }
body > div:nth-child(5) { margin: 50px; padding: 50px; }
body > div:nth-child(6) { margin: 100px; padding: 100px; }
body > div:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
body > div:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
body > div:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
body > div:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
body > div:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
body > div:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
body > div:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) { margin: 10px; padding: 0px; }
body > div:nth-child(2) { margin: 0px; padding: 10px; }
body > div:nth-child(3) { margin: 10px; padding: 10px; }
body > div:nth-child(4) { margin: 5px; padding: 5px; }
body > div:nth-child(5) { margin: 50px; padding: 50px; }
body > div:nth-child(6) { margin: 100px; padding: 100px; }
body > div:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
body > div:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
body > div:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
body > div:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
body > div:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
body > div:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
body > div:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body dir='rtl'>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter:nth-child(1) { margin: 10px; padding: 0px; }
meter:nth-child(2) { margin: 0px; padding: 10px; }
meter:nth-child(3) { margin: 10px; padding: 10px; }
meter:nth-child(4) { margin: 5px; padding: 5px; }
meter:nth-child(5) { margin: 50px; padding: 50px; }
meter:nth-child(6) { margin: 100px; padding: 100px; }
meter:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
meter:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
meter:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
meter:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
meter:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
meter:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
meter:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
meter:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
meter:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
meter:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body dir='rtl'>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) { margin: 10px; padding: 0px; }
body > div:nth-child(2) { margin: 0px; padding: 10px; }
body > div:nth-child(3) { margin: 10px; padding: 10px; }
body > div:nth-child(4) { margin: 5px; padding: 5px; }
body > div:nth-child(5) { margin: 50px; padding: 50px; }
body > div:nth-child(6) { margin: 100px; padding: 100px; }
body > div:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
body > div:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
body > div:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
body > div:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
body > div:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
body > div:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
body > div:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) { margin: 10px; padding: 0px; }
body > div:nth-child(2) { margin: 0px; padding: 10px; }
body > div:nth-child(3) { margin: 10px; padding: 10px; }
body > div:nth-child(4) { margin: 5px; padding: 5px; }
body > div:nth-child(5) { margin: 50px; padding: 50px; }
body > div:nth-child(6) { margin: 100px; padding: 100px; }
body > div:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
body > div:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
body > div:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
body > div:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
body > div:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
body > div:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
body > div:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
body > div:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
body > div:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
body > div:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body dir='rtl'>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
-moz-orient: vertical;
}
meter:nth-child(1) { margin: 10px; padding: 0px; }
meter:nth-child(2) { margin: 0px; padding: 10px; }
meter:nth-child(3) { margin: 10px; padding: 10px; }
meter:nth-child(4) { margin: 5px; padding: 5px; }
meter:nth-child(5) { margin: 50px; padding: 50px; }
meter:nth-child(6) { margin: 100px; padding: 100px; }
meter:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
meter:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
meter:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
meter:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
meter:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
meter:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
meter:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
meter:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
meter:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
meter:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body dir='rtl'>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
-moz-orient: vertical;
}
meter:nth-child(1) { margin: 10px; padding: 0px; }
meter:nth-child(2) { margin: 0px; padding: 10px; }
meter:nth-child(3) { margin: 10px; padding: 10px; }
meter:nth-child(4) { margin: 5px; padding: 5px; }
meter:nth-child(5) { margin: 50px; padding: 50px; }
meter:nth-child(6) { margin: 100px; padding: 100px; }
meter:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
meter:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
meter:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
meter:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
meter:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
meter:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
meter:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
meter:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
meter:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
meter:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter:nth-child(1) { margin: 10px; padding: 0px; }
meter:nth-child(2) { margin: 0px; padding: 10px; }
meter:nth-child(3) { margin: 10px; padding: 10px; }
meter:nth-child(4) { margin: 5px; padding: 5px; }
meter:nth-child(5) { margin: 50px; padding: 50px; }
meter:nth-child(6) { margin: 100px; padding: 100px; }
meter:nth-child(7) { margin: 10px 0px 0px 0px; padding: 0px; }
meter:nth-child(8) { margin: 0px 10px 0px 0px; padding: 0px; }
meter:nth-child(9) { margin: 0px 0px 10px 0px; padding: 0px; }
meter:nth-child(10) { margin: 0px 0px 0px 10px; padding: 0px; }
meter:nth-child(11) { margin: 0px; padding: 10px 0px 0px 0px; }
meter:nth-child(12) { margin: 0px; padding: 0px 10px 0px 0px; }
meter:nth-child(13) { margin: 0px; padding: 0px 0px 10px 0px; }
meter:nth-child(14) { margin: 0px; padding: 0px 0px 0px 10px; }
meter:nth-child(15) { margin: 0px; padding: 2px 4px 6px 8px; }
meter:nth-child(16) { margin: 2px 4px 6px 8px; padding: 0px; }
</style>
<body>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,26 @@
== values.html values-ref.html
== values-rtl.html values-rtl-ref.html
== margin-padding.html margin-padding-ref.html
== margin-padding-rtl.html margin-padding-rtl-ref.html
== bar-pseudo-element.html bar-pseudo-element-ref.html
== bar-pseudo-element-rtl.html bar-pseudo-element-rtl-ref.html
# vertical tests
== values-vertical.html values-vertical-ref.html
== values-vertical-rtl.html values-vertical-rtl-ref.html
== margin-padding-vertical.html margin-padding-vertical-ref.html
== margin-padding-vertical-rtl.html margin-padding-vertical-rtl-ref.html
== bar-pseudo-element-vertical.html bar-pseudo-element-vertical-ref.html
== bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl-ref.html
# The following test is disabled but kept in the repository because the
# transformations will not behave exactly the same for <meter> and two divs.
# However, it would be possible to manually check those.
# == transformations.html transformations-ref.html
# default style
include default-style/reftest.list
# Tests for bugs:
== block-invalidate.html block-invalidate-ref.html
== in-cells.html in-cells-ref.html

View File

@ -0,0 +1,38 @@
div.meter-element {
display: inline-block;
height: 1em;
width: 5em;
vertical-align: -0.2em;
background-color: grey;
}
div.meter-element.vertical {
height: 5em;
width: 1em;
}
div.meter-bar {
float: none ! important;
height: 100%;
/*
* We can't apply the following style to the reference because it will have
* underisable effectes:
* width: 100%;
*/
background-color: green;
}
meter, meter::-moz-meter-bar, div.meter-element, div.meter-bar {
-moz-appearance: none;
}
meter {
background: grey;
}
meter::-moz-meter-bar {
background: green;
}

View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
body > div:nth-child(1) { -moz-transform: matrix(1, -0.2, 0, 1, 0, 0); }
body > div:nth-child(2) { -moz-transform: matrix(1, 0, 0.6, 1, 15em, 0); }
body > div:nth-child(3) { -moz-transform: rotate(30deg); }
body > div:nth-child(4) { -moz-transform: scale(2, 4); }
body > div:nth-child(5) { -moz-transform: scale(0.1, 0.4); }
body > div:nth-child(6) { -moz-transform: scale(1, 0.4); }
body > div:nth-child(7) { -moz-transform: scale(0.1, 1); }
body > div:nth-child(8) { -moz-transform: skew(30deg, -10deg); }
body > div:nth-child(9) { -moz-transform: skew(-30deg, 10deg); }
body > div:nth-child(10) { -moz-transform: translate(10px, 30px); }
body > div:nth-child(11) { -moz-transform: translate(30px, 10px); }
body > div:nth-child(12) { -moz-transform: translate(-10px, 30px); }
body > div:nth-child(13) { -moz-transform: translate(30px, -10px); }
body > div:nth-child(14) { -moz-transform: scale(0, 0); }
</style>
<body>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter:nth-child(1) { -moz-transform: matrix(1, -0.2, 0, 1, 0, 0); }
meter:nth-child(2) { -moz-transform: matrix(1, 0, 0.6, 1, 15em, 0); }
meter:nth-child(3) { -moz-transform: rotate(30deg); }
meter:nth-child(4) { -moz-transform: scale(2, 4); }
meter:nth-child(5) { -moz-transform: scale(0.1, 0.4); }
meter:nth-child(6) { -moz-transform: scale(1, 0.4); }
meter:nth-child(7) { -moz-transform: scale(0.1, 1); }
meter:nth-child(8) { -moz-transform: skew(30deg, -10deg); }
meter:nth-child(9) { -moz-transform: skew(-30deg, 10deg); }
meter:nth-child(10) { -moz-transform: translate(10px, 30px); }
meter:nth-child(11) { -moz-transform: translate(30px, 10px); }
meter:nth-child(12) { -moz-transform: translate(-10px, 30px); }
meter:nth-child(13) { -moz-transform: translate(30px, -10px); }
meter:nth-child(14) { -moz-transform: scale(0, 0); }
</style>
<body>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
<meter value='1'></meter>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
div:nth-child(1) > .meter-bar { width: 100%; }
div:nth-child(2) > .meter-bar { width: 0%; }
div:nth-child(3) > .meter-bar { width: 10%; }
div:nth-child(4) > .meter-bar { width: 50%; }
div:nth-child(5) > .meter-bar { width: 0%; }
div:nth-child(6) > .meter-bar { width: 100%; }
div:nth-child(7) > .meter-bar { width: 42%; }
div:nth-child(8) > .meter-bar { width: 100%; }
div:nth-child(9) > .meter-bar { width: 100%; }
div:nth-child(10) > .meter-bar { width: 10%; }
div:nth-child(11) > .meter-bar { width: 37.5%; }
div:nth-child(12) > .meter-bar { width: 100%; }
div:nth-child(13) > .meter-bar { width: 100%; }
div:nth-child(14) > .meter-bar { width: 0%; }
div:nth-child(15) > .meter-bar { width: 55%; }
div:nth-child(16) > .meter-bar { width: 50%; }
div:nth-child(17) > .meter-bar { width: 20%; }
div:nth-child(18) > .meter-bar { width: 10%; }
div:nth-child(19) > .meter-bar { width: 10%; }
div:nth-child(20) > .meter-bar { width: 20%; }
div:nth-child(21) > .meter-bar { width: 37.5%; }
div:nth-child(22) > .meter-bar { width: 10%; }
div:nth-child(23) > .meter-bar { width: 10%; }
div:nth-child(24) > .meter-bar { width: 10%; }
div:nth-child(25) > .meter-bar { width: 50%; }
div:nth-child(26) > .meter-bar { width: 20%; }
div:nth-child(27) > .meter-bar { width: 90%; }
div:nth-child(28) > .meter-bar { width: 10%; }
div:nth-child(29) > .meter-bar { width: 10%; }
div:nth-child(30) > .meter-bar { width: 10%; }
div:nth-child(31) > .meter-bar { width: 10%; }
</style>
<body>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
div:nth-child(1) > .meter-bar { width: 100%; }
div:nth-child(2) > .meter-bar { width: 0%; }
div:nth-child(3) > .meter-bar { width: 10%; }
div:nth-child(4) > .meter-bar { width: 50%; }
div:nth-child(5) > .meter-bar { width: 0%; }
div:nth-child(6) > .meter-bar { width: 100%; }
div:nth-child(7) > .meter-bar { width: 42%; }
div:nth-child(8) > .meter-bar { width: 100%; }
div:nth-child(9) > .meter-bar { width: 100%; }
div:nth-child(10) > .meter-bar { width: 10%; }
div:nth-child(11) > .meter-bar { width: 37.5%; }
div:nth-child(12) > .meter-bar { width: 100%; }
div:nth-child(13) > .meter-bar { width: 100%; }
div:nth-child(14) > .meter-bar { width: 0%; }
div:nth-child(15) > .meter-bar { width: 55%; }
div:nth-child(16) > .meter-bar { width: 50%; }
div:nth-child(17) > .meter-bar { width: 20%; }
div:nth-child(18) > .meter-bar { width: 10%; }
div:nth-child(19) > .meter-bar { width: 10%; }
div:nth-child(20) > .meter-bar { width: 20%; }
div:nth-child(21) > .meter-bar { width: 37.5%; }
div:nth-child(22) > .meter-bar { width: 10%; }
div:nth-child(23) > .meter-bar { width: 10%; }
div:nth-child(24) > .meter-bar { width: 10%; }
div:nth-child(25) > .meter-bar { width: 50%; }
div:nth-child(26) > .meter-bar { width: 20%; }
div:nth-child(27) > .meter-bar { width: 90%; }
div:nth-child(28) > .meter-bar { width: 10%; }
div:nth-child(29) > .meter-bar { width: 10%; }
div:nth-child(30) > .meter-bar { width: 10%; }
div:nth-child(31) > .meter-bar { width: 10%; }
</style>
<body dir='rtl'>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
<div class="meter-element">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<body dir='rtl'>
<meter value="1.0"></meter>
<meter value="0.0"></meter>
<meter value="0.1"></meter>
<meter value="0.5"></meter>
<meter value="-1"></meter>
<meter value="50"></meter>
<!-- focus on max -->
<meter value="42" max="100"></meter>
<meter value="42" max="1"></meter>
<meter value="42" max="-1"></meter>
<meter value="0.1" max="1"></meter>
<!-- focus on min -->
<meter value="50" min="20" max="100"></meter>
<meter value="50" min="1" ></meter>
<meter value="0.1" min="2" ></meter>
<meter value="0.1" min="0.1"></meter>
<meter value="0.1" min="-1"></meter>
<!-- focus on low -->
<meter value="50" low="20" max="100"></meter>
<meter value="20" low="50" max="100"></meter>
<meter value="0.1" low="-1"></meter>
<meter value="0.1" low="0"></meter>
<!-- focus on high -->
<meter value="20" high="50" max="100"></meter>
<meter value="50" min="20" high="1" max="100"></meter>
<meter value="0.1" low="0.3" high="0.2"></meter>
<meter value="0.1" high="-1"></meter>
<meter value="0.1" high="2"></meter>
<!-- focus on optimum -->
<meter value="50" max="100" optimum="20"></meter>
<meter value="20" max="100" low="40" high="50" optimum="20"></meter>
<meter value="90" max="100" low="40" high="50" optimum="20"></meter>
<meter value="10" max="100" low="20" high="40" optimum="50"></meter>
<meter value="0.1" optimum="50"></meter>
<meter value="0.1" optimum="-1"></meter>
<meter value="0.1" optimum="1"></meter>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
div:nth-child(1) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(2) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(3) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(4) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(5) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(6) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(7) > .meter-bar { position: relative; top: 58%; height: 42%; }
div:nth-child(8) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(9) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(10) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(11) > .meter-bar { position: relative; top: 62.5%; height: 37.5%; }
div:nth-child(12) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(13) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(14) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(15) > .meter-bar { position: relative; top: 45%; height: 55%; }
div:nth-child(16) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(17) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(18) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(19) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(20) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(21) > .meter-bar { position: relative; top: 62.5%; height: 37.5%; }
div:nth-child(22) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(23) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(24) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(25) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(26) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(27) > .meter-bar { position: relative; top: 10%; height: 90%; }
div:nth-child(28) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(29) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(30) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(31) > .meter-bar { position: relative; top: 90%; height: 10%; }
</style>
<body>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
div:nth-child(1) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(2) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(3) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(4) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(5) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(6) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(7) > .meter-bar { position: relative; top: 58%; height: 42%; }
div:nth-child(8) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(9) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(10) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(11) > .meter-bar { position: relative; top: 62.5%; height: 37.5%; }
div:nth-child(12) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(13) > .meter-bar { position: relative; top: 0%; height: 100%; }
div:nth-child(14) > .meter-bar { position: relative; top: 100%; height: 0%; }
div:nth-child(15) > .meter-bar { position: relative; top: 45%; height: 55%; }
div:nth-child(16) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(17) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(18) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(19) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(20) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(21) > .meter-bar { position: relative; top: 62.5%; height: 37.5%; }
div:nth-child(22) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(23) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(24) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(25) > .meter-bar { position: relative; top: 50%; height: 50%; }
div:nth-child(26) > .meter-bar { position: relative; top: 80%; height: 20%; }
div:nth-child(27) > .meter-bar { position: relative; top: 10%; height: 90%; }
div:nth-child(28) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(29) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(30) > .meter-bar { position: relative; top: 90%; height: 10%; }
div:nth-child(31) > .meter-bar { position: relative; top: 90%; height: 10%; }
</style>
<body dir='rtl'>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
<div class="meter-element vertical">
<div class="meter-bar">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
-moz-orient: vertical;
}
</style>
<body dir='rtl'>
<meter value="1.0"></meter>
<meter value="0.0"></meter>
<meter value="0.1"></meter>
<meter value="0.5"></meter>
<meter value="-1"></meter>
<meter value="50"></meter>
<!-- focus on max -->
<meter value="42" max="100"></meter>
<meter value="42" max="1"></meter>
<meter value="42" max="-1"></meter>
<meter value="0.1" max="1"></meter>
<!-- focus on min -->
<meter value="50" min="20" max="100"></meter>
<meter value="50" min="1" ></meter>
<meter value="0.1" min="2" ></meter>
<meter value="0.1" min="0.1"></meter>
<meter value="0.1" min="-1"></meter>
<!-- focus on low -->
<meter value="50" low="20" max="100"></meter>
<meter value="20" low="50" max="100"></meter>
<meter value="0.1" low="-1"></meter>
<meter value="0.1" low="0"></meter>
<!-- focus on high -->
<meter value="20" high="50" max="100"></meter>
<meter value="50" min="20" high="1" max="100"></meter>
<meter value="0.1" low="0.3" high="0.2"></meter>
<meter value="0.1" high="-1"></meter>
<meter value="0.1" high="2"></meter>
<!-- focus on optimum -->
<meter value="50" max="100" optimum="20"></meter>
<meter value="20" max="100" low="40" high="50" optimum="20"></meter>
<meter value="90" max="100" low="40" high="50" optimum="20"></meter>
<meter value="10" max="100" low="20" high="40" optimum="50"></meter>
<meter value="0.1" optimum="50"></meter>
<meter value="0.1" optimum="-1"></meter>
<meter value="0.1" optimum="1"></meter>
</body>
</html>

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<style>
meter {
-moz-orient: vertical;
}
</style>
<body>
<meter value="1.0"></meter>
<meter value="0.0"></meter>
<meter value="0.1"></meter>
<meter value="0.5"></meter>
<meter value="-1"></meter>
<meter value="50"></meter>
<!-- focus on max -->
<meter value="42" max="100"></meter>
<meter value="42" max="1"></meter>
<meter value="42" max="-1"></meter>
<meter value="0.1" max="1"></meter>
<!-- focus on min -->
<meter value="50" min="20" max="100"></meter>
<meter value="50" min="1" ></meter>
<meter value="0.1" min="2" ></meter>
<meter value="0.1" min="0.1"></meter>
<meter value="0.1" min="-1"></meter>
<!-- focus on low -->
<meter value="50" low="20" max="100"></meter>
<meter value="20" low="50" max="100"></meter>
<meter value="0.1" low="-1"></meter>
<meter value="0.1" low="0"></meter>
<!-- focus on high -->
<meter value="20" high="50" max="100"></meter>
<meter value="50" min="20" high="1" max="100"></meter>
<meter value="0.1" low="0.3" high="0.2"></meter>
<meter value="0.1" high="-1"></meter>
<meter value="0.1" high="2"></meter>
<!-- focus on optimum -->
<meter value="50" max="100" optimum="20"></meter>
<meter value="20" max="100" low="40" high="50" optimum="20"></meter>
<meter value="90" max="100" low="40" high="50" optimum="20"></meter>
<meter value="10" max="100" low="20" high="40" optimum="50"></meter>
<meter value="0.1" optimum="50"></meter>
<meter value="0.1" optimum="-1"></meter>
<meter value="0.1" optimum="1"></meter>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<body>
<meter value="1.0"></meter>
<meter value="0.0"></meter>
<meter value="0.1"></meter>
<meter value="0.5"></meter>
<meter value="-1"></meter>
<meter value="50"></meter>
<!-- focus on max -->
<meter value="42" max="100"></meter>
<meter value="42" max="1"></meter>
<meter value="42" max="-1"></meter>
<meter value="0.1" max="1"></meter>
<!-- focus on min -->
<meter value="50" min="20" max="100"></meter>
<meter value="50" min="1" ></meter>
<meter value="0.1" min="2" ></meter>
<meter value="0.1" min="0.1"></meter>
<meter value="0.1" min="-1"></meter>
<!-- focus on low -->
<meter value="50" low="20" max="100"></meter>
<meter value="20" low="50" max="100"></meter>
<meter value="0.1" low="-1"></meter>
<meter value="0.1" low="0"></meter>
<!-- focus on high -->
<meter value="20" high="50" max="100"></meter>
<meter value="50" min="20" high="1" max="100"></meter>
<meter value="0.1" low="0.3" high="0.2"></meter>
<meter value="0.1" high="-1"></meter>
<meter value="0.1" high="2"></meter>
<!-- focus on optimum -->
<meter value="50" max="100" optimum="20"></meter>
<meter value="20" max="100" low="40" high="50" optimum="20"></meter>
<meter value="90" max="100" low="40" high="50" optimum="20"></meter>
<meter value="10" max="100" low="20" high="40" optimum="50"></meter>
<meter value="0.1" optimum="50"></meter>
<meter value="0.1" optimum="-1"></meter>
<meter value="0.1" optimum="1"></meter>
</body>
</html>

View File

@ -9,12 +9,12 @@
<table>
<tr>
<td>foo</td>
<td><progress value='0.5'></td>
<td><progress value='0.5'></progress></td>
<td>bar</td>
</tr>
<tr>
<td>foo</td>
<td><progress class='vertical' value='0.5'></td>
<td><progress class='vertical' value='0.5'></progress></td>
<td>bar</td>
</tr>
</table>

View File

@ -8,12 +8,12 @@
<table>
<tr>
<td>foo</td>
<td><progress value='0.5'></td>
<td><progress value='0.5'></progress></td>
<td>bar</td>
</tr>
<tr>
<td>foo</td>
<td><progress class='vertical' value='0.5'></td>
<td><progress class='vertical' value='0.5'></progress></td>
<td>bar</td>
</tr>
</table>

View File

@ -666,6 +666,39 @@ progress {
background-color: #0064b4; /* blue */
}
meter {
-moz-appearance: meterbar;
display: inline-block;
vertical-align: -0.2em;
background: -moz-linear-gradient(top, #e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
}
::-moz-meter-bar {
/* Block styles that would change the type of frame we construct. */
display: inline-block ! important;
float: none ! important;
position: static ! important;
overflow: visible ! important;
-moz-appearance: meterchunk;
height: 100%;
width: 100%;
}
:-moz-meter-optimum::-moz-meter-bar {
/* green. */
background: -moz-linear-gradient(top, #ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
}
:-moz-meter-sub-optimum::-moz-meter-bar {
/* orange. */
background: -moz-linear-gradient(top, #fe7, #fe7, #ffc 20%, #db3 45%, #db3 55%);
}
:-moz-meter-sub-sub-optimum::-moz-meter-bar {
/* red. */
background: -moz-linear-gradient(top, #f77, #f77, #fcc 20%, #d44 45%, #d44 55%);
}
%ifdef XP_OS2
input {
font: medium serif; font-family: inherit

View File

@ -535,6 +535,8 @@ CSS_KEY(menulist, menulist)
CSS_KEY(menulist-button, menulistbutton)
CSS_KEY(menulist-text, menulisttext)
CSS_KEY(menulist-textfield, menulisttextfield)
CSS_KEY(meterbar, meterbar)
CSS_KEY(meterchunk, meterchunk)
CSS_KEY(scale-horizontal, scale_horizontal)
CSS_KEY(scale-vertical, scale_vertical)
CSS_KEY(scalethumb-horizontal, scalethumb_horizontal)

View File

@ -480,6 +480,8 @@ const PRInt32 nsCSSProps::kAppearanceKTable[] = {
eCSSKeyword_button_arrow_down, NS_THEME_BUTTON_ARROW_DOWN,
eCSSKeyword_button_arrow_next, NS_THEME_BUTTON_ARROW_NEXT,
eCSSKeyword_button_arrow_previous, NS_THEME_BUTTON_ARROW_PREVIOUS,
eCSSKeyword_meterbar, NS_THEME_METERBAR,
eCSSKeyword_meterchunk, NS_THEME_METERBAR_CHUNK,
eCSSKeyword_separator, NS_THEME_TOOLBAR_SEPARATOR,
eCSSKeyword_splitter, NS_THEME_SPLITTER,
eCSSKeyword_statusbar, NS_THEME_STATUSBAR,

View File

@ -161,6 +161,12 @@ CSS_STATE_PSEUDO_CLASS(mozUIInvalid, ":-moz-ui-invalid",
NS_EVENT_STATE_MOZ_UI_INVALID)
CSS_STATE_PSEUDO_CLASS(mozUIValid, ":-moz-ui-valid",
NS_EVENT_STATE_MOZ_UI_VALID)
CSS_STATE_PSEUDO_CLASS(mozMeterOptimum, ":-moz-meter-optimum",
NS_EVENT_STATE_OPTIMUM)
CSS_STATE_PSEUDO_CLASS(mozMeterSubOptimum, ":-moz-meter-sub-optimum",
NS_EVENT_STATE_SUB_OPTIMUM)
CSS_STATE_PSEUDO_CLASS(mozMeterSubSubOptimum, ":-moz-meter-sub-sub-optimum",
NS_EVENT_STATE_SUB_SUB_OPTIMUM)
#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
#undef DEFINED_CSS_STATE_PSEUDO_CLASS

View File

@ -53,4 +53,5 @@ CSS_PSEUDO_ELEMENT(mozMathAnonymous, ":-moz-math-anonymous", 0)
// HTML5 Forms pseudo elements
CSS_PSEUDO_ELEMENT(mozProgressBar, ":-moz-progress-bar", 0)
CSS_PSEUDO_ELEMENT(mozMeterBar, ":-moz-meter-bar", 0)

View File

@ -110,6 +110,7 @@ HTML_TAG(marquee, Div)
HTML_TAG(menu, Menu)
HTML_TAG(menuitem, MenuItem)
HTML_TAG(meta, Meta)
HTML_TAG(meter, Meter)
HTML_TAG(multicol, Span)
HTML_HTMLELEMENT_TAG(nav)
HTML_HTMLELEMENT_TAG(nobr)

View File

@ -840,6 +840,15 @@ const nsHTMLElement gHTMLElements[] = {
/*special props, prop-range*/ kNoStyleLeaksIn|kNonContainer, kDefaultPropRange,
/*special parents,kids*/ &gInHead,0,
},
{
/*tag*/ eHTMLTag_meter,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kFormControl, kFlowEntity, kNone,
/*special props, prop-range*/ 0,kDefaultPropRange,
/*special parents,kids*/ 0,0,
},
{
/*tag*/ eHTMLTag_multicol,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,

View File

@ -172,6 +172,8 @@ static const PRUnichar sHTMLTagUnicodeName_menuitem[] =
{'m', 'e', 'n', 'u', 'i', 't', 'e', 'm', '\0'};
static const PRUnichar sHTMLTagUnicodeName_meta[] =
{'m', 'e', 't', 'a', '\0'};
static const PRUnichar sHTMLTagUnicodeName_meter[] =
{'m', 'e', 't', 'e', 'r', '\0'};
static const PRUnichar sHTMLTagUnicodeName_multicol[] =
{'m', 'u', 'l', 't', 'i', 'c', 'o', 'l', '\0'};
static const PRUnichar sHTMLTagUnicodeName_nav[] =

View File

@ -79,6 +79,8 @@ protected:
void DrawProgress(CGContextRef context, const HIRect& inBoxRect,
bool inIsIndeterminate, bool inIsHorizontal,
double inValue, double inMaxValue, nsIFrame* aFrame);
void DrawMeter(CGContextRef context, const HIRect& inBoxRect,
nsIFrame* aFrame);
void DrawSegment(CGContextRef cgContext, const HIRect& inBoxRect,
nsEventStates inState, nsIFrame* aFrame,
const SegmentedControlRenderSettings& aSettings);
@ -126,6 +128,7 @@ private:
NSPopUpButtonCell* mDropdownCell;
NSComboBoxCell* mComboBoxCell;
NSProgressBarCell* mProgressBarCell;
NSLevelIndicatorCell* mMeterBarCell;
CellDrawView* mCellDrawView;
};

View File

@ -24,6 +24,8 @@
#include "nsNativeThemeColors.h"
#include "nsIScrollableFrame.h"
#include "nsIDOMHTMLProgressElement.h"
#include "nsIDOMHTMLMeterElement.h"
#include "mozilla/dom/Element.h"
#include "gfxContext.h"
#include "gfxQuartzSurface.h"
@ -422,6 +424,9 @@ nsNativeThemeCocoa::nsNativeThemeCocoa()
mProgressBarCell = [[NSProgressBarCell alloc] init];
mMeterBarCell = [[NSLevelIndicatorCell alloc]
initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle];
mCellDrawView = [[CellDrawView alloc] init];
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -431,6 +436,7 @@ nsNativeThemeCocoa::~nsNativeThemeCocoa()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[mMeterBarCell release];
[mProgressBarCell release];
[mPushButtonCell release];
[mRadioButtonCell release];
@ -1335,6 +1341,121 @@ nsNativeThemeCocoa::DrawProgress(CGContextRef cgContext, const HIRect& inBoxRect
NS_OBJC_END_TRY_ABORT_BLOCK;
}
static const CellRenderSettings meterSetting = {
{
NSMakeSize(0, 16), // mini
NSMakeSize(0, 16), // small
NSMakeSize(0, 16) // regular
},
{
NSZeroSize, NSZeroSize, NSZeroSize
},
{
{ // Leopard
{1, 1, 1, 1}, // mini
{1, 1, 1, 1}, // small
{1, 1, 1, 1} // regular
}
}
};
void
nsNativeThemeCocoa::DrawMeter(CGContextRef cgContext, const HIRect& inBoxRect,
nsIFrame* aFrame)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK
NS_PRECONDITION(aFrame, "aFrame should not be null here!");
nsCOMPtr<nsIDOMHTMLMeterElement> meterElement =
do_QueryInterface(aFrame->GetContent());
// When using -moz-meterbar on an non meter element, we will not be able to
// get all the needed information so we just draw an empty meter.
if (!meterElement) {
DrawCellWithSnapping(mMeterBarCell, cgContext, inBoxRect,
meterSetting, VerticalAlignFactor(aFrame),
mCellDrawView, IsFrameRTL(aFrame));
return;
}
double value;
double min;
double max;
double low;
double high;
double optimum;
// NOTE: if we were allowed to static_cast to nsHTMLMeterElement we would be
// able to use nicer getters...
meterElement->GetValue(&value);
meterElement->GetMin(&min);
meterElement->GetMax(&max);
meterElement->GetLow(&low);
meterElement->GetHigh(&high);
meterElement->GetOptimum(&optimum);
NSLevelIndicatorCell* cell = mMeterBarCell;
[cell setMinValue:min];
[cell setMaxValue:max];
[cell setDoubleValue:value];
/**
* The way HTML and Cocoa defines the meter/indicator widget are different.
* So, we are going to use a trick to get the Cocoa widget showing what we
* are expecting: we set the warningValue or criticalValue to the current
* value when we want to have the widget to be in the warning or critical
* state.
*/
nsEventStates states = aFrame->GetContent()->AsElement()->State();
// Reset previously set warning and critical values.
[cell setWarningValue:max+1];
[cell setCriticalValue:max+1];
if (states.HasState(NS_EVENT_STATE_SUB_OPTIMUM)) {
[cell setWarningValue:value];
} else if (states.HasState(NS_EVENT_STATE_SUB_SUB_OPTIMUM)) {
[cell setCriticalValue:value];
}
HIRect rect = CGRectStandardize(inBoxRect);
BOOL vertical = IsVerticalMeter(aFrame);
CGContextSaveGState(cgContext);
if (vertical) {
/**
* Cocoa doesn't provide a vertical meter bar so to show one, we have to
* show a rotated horizontal meter bar.
* Given that we want to show a vertical meter bar, we assume that the rect
* has vertical dimensions but we can't correctly draw a meter widget inside
* such a rectangle so we need to inverse width and height (and re-position)
* to get a rectangle with horizontal dimensions.
* Finally, we want to show a vertical meter so we want to rotate the result
* so it is vertical. We do that by changing the context.
*/
CGFloat tmp = rect.size.width;
rect.size.width = rect.size.height;
rect.size.height = tmp;
rect.origin.x += rect.size.height / 2.f - rect.size.width / 2.f;
rect.origin.y += rect.size.width / 2.f - rect.size.height / 2.f;
CGContextTranslateCTM(cgContext, CGRectGetMidX(rect), CGRectGetMidY(rect));
CGContextRotateCTM(cgContext, -M_PI / 2.f);
CGContextTranslateCTM(cgContext, -CGRectGetMidX(rect), -CGRectGetMidY(rect));
}
DrawCellWithSnapping(cell, cgContext, rect,
meterSetting, VerticalAlignFactor(aFrame),
mCellDrawView, !vertical && IsFrameRTL(aFrame));
CGContextRestoreGState(cgContext);
NS_OBJC_END_TRY_ABORT_BLOCK
}
void
nsNativeThemeCocoa::DrawTabPanel(CGContextRef cgContext, const HIRect& inBoxRect,
nsIFrame* aFrame)
@ -2028,9 +2149,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
GetProgressMaxValue(aFrame), aFrame);
break;
case NS_THEME_METERBAR:
DrawMeter(cgContext, macRect, aFrame);
break;
case NS_THEME_PROGRESSBAR_CHUNK:
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
// do nothing, covered by the progress bar cases above
case NS_THEME_METERBAR_CHUNK:
// Do nothing: progress and meter bars cases will draw chunks.
break;
case NS_THEME_TREEVIEW_TWISTY:
@ -2614,6 +2740,8 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
case NS_THEME_PROGRESSBAR:
case NS_THEME_PROGRESSBAR_VERTICAL:
case NS_THEME_METERBAR:
case NS_THEME_METERBAR_CHUNK:
*aShouldRepaint = false;
return NS_OK;
}
@ -2698,6 +2826,8 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
case NS_THEME_PROGRESSBAR_VERTICAL:
case NS_THEME_PROGRESSBAR_CHUNK:
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
case NS_THEME_METERBAR:
case NS_THEME_METERBAR_CHUNK:
case NS_THEME_TOOLBAR_SEPARATOR:
case NS_THEME_TAB_PANELS:
@ -2764,6 +2894,7 @@ nsNativeThemeCocoa::WidgetIsContainer(PRUint8 aWidgetType)
case NS_THEME_RADIO:
case NS_THEME_CHECKBOX:
case NS_THEME_PROGRESSBAR:
case NS_THEME_METERBAR:
return false;
break;
}

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<style>
div.meter-element {
/**
* The purpose of this test is to not show the native style.
* -moz-appearance: meterbar;
*/
display: inline-block;
height: 1em;
width: 5em;
vertical-align: -0.2em;
background: -moz-linear-gradient(top, #e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
}
div.meter-bar {
/**
* The purpose of this test is to not show the native style.
* -moz-appearance: meterchunk;
*/
height: 100%;
width: 100%;
background: -moz-linear-gradient(top, #ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
}
div.meter-element { padding: 5px; }
body > div:nth-child(1) { -moz-appearance: none; }
body > div:nth-child(2) > .meter-bar { -moz-appearance: none; }
body > div:nth-child(3) { background: red; }
body > div:nth-child(4) > .meter-bar { background: red; }
body > div:nth-child(5) { border: 2px solid red; }
body > div:nth-child(6) > .meter-bar { border: 5px solid red; width: -moz-calc(100% - 10px); }
</style>
<body>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
<div class="meter-element">
<div class="meter-bar"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<style>
meter { padding: 5px }
body > meter:nth-child(1) { -moz-appearance: none; }
body > meter:nth-child(2)::-moz-meter-bar { -moz-appearance: none; }
body > meter:nth-child(3) { background: red; }
body > meter:nth-child(4)::-moz-meter-bar { background: red; }
body > meter:nth-child(5) { border: 2px solid red; }
body > meter:nth-child(6)::-moz-meter-bar { border: 5px solid red; }
</style>
<body>
<meter value=1></meter>
<meter value=1></meter>
<meter value=1></meter>
<meter value=1></meter>
<meter value=1></meter>
<meter value=1></meter>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<body>
<!-- Empty meter, no bar. -->
<meter></meter>
<!-- Full meter green colored. -->
<meter min=0 low=0 high=1 optimum=2 max=10 value=10></meter>
<!-- Full meter orange colored. -->
<meter min=0 low=0 high=1 optimum=1 max=10 value=10></meter>
<!-- Full meter red colored. -->
<meter min=0 low=1 high=2 optimum=0 max=10 value=10></meter>
<!-- Half-empty orange colored. -->
<meter min=0 low=0 high=1 optimum=0 max=10 value=5></meter>
<!-- Half-empty orange colored. -->
<meter min=0 low=0 high=1 optimum=0 max=10 value=5></meter>
<!-- With RTL, the bar should begin on the right. -->
<meter style="-moz-transform: scale(-1, 1);" value=0.5></meter>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<body>
<meter vaue=0></meter>
<!-- Should be green. -->
<meter min=0 low=0 high=10 optimum=10 max=10 value=10></meter>
<!-- Should be orange. -->
<meter min=0 low=9 high=10 optimum=8 max=10 value=10></meter>
<!-- Should be red. -->
<meter min=0 low=8 high=9 optimum=0 max=10 value=10></meter>
<!-- Half-full orange. -->
<meter min=0 low=3 high=4 optimum=4 max=10 value=5></meter>
<!-- Half-full orange. -->
<meter min=0 low=9 high=10 optimum=10 max=10 value=5></meter>
<!-- Test RTL -->
<meter dir='rtl' value=0.5></meter>
</body>
</html>

View File

@ -0,0 +1,14 @@
<html>
<style>
meter:nth-child(1) { -moz-transform: rotate(-90deg) translate(-2em, -2em); }
meter:nth-child(2) { -moz-transform: rotate(-90deg) translate(-2em, -6em); }
meter:nth-child(3) { -moz-transform: rotate(-90deg) translate(-2em, -10em); }
meter:nth-child(4) { -moz-transform: rotate(-90deg) translate(-2em, -14em); }
meter:nth-child(5) { -moz-transform: rotate(-90deg) translate(-2em, -18em); }
meter:nth-child(6) { -moz-transform: rotate(-90deg) translate(-2em, -22em); }
meter:nth-child(7) { -moz-transform: rotate(-90deg) translate(-2em, -26em); }
</style>
<body>
<meter></meter><meter min=0 low=0 high=1 optimum=2 max=10 value=10></meter><meter min=0 low=0 high=1 optimum=1 max=10 value=10></meter><meter min=0 low=1 high=2 optimum=0 max=10 value=10></meter><meter min=0 low=0 high=1 optimum=0 max=10 value=5></meter><meter min=0 low=0 high=1 optimum=0 max=10 value=5></meter><meter value=0.5></meter>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<style>
meter { -moz-orient: vertical; }
</style>
<body>
<!-- For some reasons, the ref has a small offset when there are spaces between meters.
Given that we don't want to test -moz-transform and even a perfect match but just
the general rendering, we are going to keep this dirty test.
It's very similar to the non-vertical test with a difference, for the RTL: RTL
does not apply for vertical meters. -->
<meter vaue=0></meter><meter min=0 low=0 high=10 optimum=10 max=10 value=10></meter><meter min=0 low=9 high=10 optimum=8 max=10 value=10></meter><meter min=0 low=8 high=9 optimum=0 max=10 value=10></meter><meter min=0 low=3 high=4 optimum=4 max=10 value=5></meter><meter min=0 low=9 high=10 optimum=10 max=10 value=5></meter><meter value=0.5 dir=rtl></meter>
</body>
</html>

View File

@ -1,3 +1,6 @@
skip-if(!cocoaWidget) != 507947.html about:blank
== progressbar-fallback-default-style.html progressbar-fallback-default-style-ref.html
== meter-native-style.html meter-native-style-ref.html
skip-if(!cocoaWidget) == meter-vertical-native-style.html meter-vertical-native-style-ref.html
== meter-fallback-default-style.html meter-fallback-default-style-ref.html
load 664925.xhtml

View File

@ -19,6 +19,7 @@
#include "nsIComponentManager.h"
#include "nsPIDOMWindow.h"
#include "nsProgressFrame.h"
#include "nsMeterFrame.h"
#include "nsMenuFrame.h"
#include "mozilla/dom/Element.h"
@ -247,6 +248,19 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame,
}
}
/**
* Meter bar appearance should be the same for the bar and the container
* frame. nsMeterFrame owns the logic and will tell us what we should do.
*/
if (aWidgetType == NS_THEME_METERBAR_CHUNK ||
aWidgetType == NS_THEME_METERBAR) {
nsMeterFrame* meterFrame = do_QueryFrame(aWidgetType == NS_THEME_METERBAR_CHUNK
? aFrame->GetParent() : aFrame);
if (meterFrame) {
return !meterFrame->ShouldUseNativeStyle();
}
}
return (aWidgetType == NS_THEME_BUTTON ||
aWidgetType == NS_THEME_TEXTFIELD ||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
@ -448,6 +462,13 @@ nsNativeTheme::IsVerticalProgress(nsIFrame* aFrame)
aFrame->GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
}
bool
nsNativeTheme::IsVerticalMeter(nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "You have to pass a non-null aFrame");
return aFrame->GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
}
// menupopup:
bool
nsNativeTheme::IsSubmenu(nsIFrame* aFrame, bool* aLeftOfParent)

View File

@ -136,6 +136,9 @@ class nsNativeTheme : public nsITimerCallback
bool IsIndeterminateProgress(nsIFrame* aFrame, nsEventStates aEventStates);
bool IsVerticalProgress(nsIFrame* aFrame);
// meter:
bool IsVerticalMeter(nsIFrame* aFrame);
// textfield:
bool IsReadOnly(nsIFrame* aFrame) {
return CheckBooleanAttr(aFrame, nsGkAtoms::readonly);