mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Merge inbound to m-c.
This commit is contained in:
commit
548f30b37c
7
.lldbinit
Normal file
7
.lldbinit
Normal file
@ -0,0 +1,7 @@
|
||||
# .lldbinit file for debugging Mozilla
|
||||
|
||||
# Mozilla's use of UNIFIED_SOURCES to include multiple source files into a
|
||||
# single compiled file breaks lldb breakpoint setting. This works around that.
|
||||
# See http://lldb.llvm.org/troubleshooting.html for more info.
|
||||
settings set target.inline-breakpoint-strategy always
|
||||
|
3
CLOBBER
3
CLOBBER
@ -18,4 +18,5 @@
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
|
||||
More Windows WebIDL changes.
|
||||
Bug 942184 - Landing and subsequent backout of bug 941450 increased the
|
||||
possibility of random build bustage.
|
||||
|
@ -600,6 +600,7 @@ pref("javascript.options.mem.gc_decommit_threshold_mb", 1);
|
||||
|
||||
// Show/Hide scrollbars when active/inactive
|
||||
pref("ui.showHideScrollbars", 1);
|
||||
pref("ui.useOverlayScrollbars", 1);
|
||||
|
||||
// Enable the ProcessPriorityManager, and give processes with no visible
|
||||
// documents a 1s grace period before they're eligible to be marked as
|
||||
|
@ -284,6 +284,10 @@ textarea:active {
|
||||
background-color: rgba(141, 184, 216, 0.5);
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-box {
|
||||
display: none;
|
||||
}
|
||||
|
||||
%ifdef MOZ_WIDGET_GONK
|
||||
/* This binding only provide key shortcuts that we can't use on devices */
|
||||
input,
|
||||
|
@ -767,6 +767,8 @@ var gPluginHandler = {
|
||||
if (aNewState != "block" && !pluginFound) {
|
||||
browser.reload();
|
||||
}
|
||||
|
||||
this._setPluginNotificationIcon(browser);
|
||||
},
|
||||
|
||||
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPlugin, aShowNow) {
|
||||
|
@ -104,6 +104,7 @@ skip-if = toolkit == "gtk2" || toolkit == "gtk3" # browser_CTP_context_menu.js
|
||||
run-if = crashreporter
|
||||
[browser_CTP_data_urls.js]
|
||||
[browser_CTP_drag_drop.js]
|
||||
[browser_CTP_hideBar.js]
|
||||
[browser_CTP_nonplugins.js]
|
||||
[browser_CTP_resize.js]
|
||||
[browser_URLBarSetURI.js]
|
||||
|
98
browser/base/content/test/general/browser_CTP_hideBar.js
Normal file
98
browser/base/content/test/general/browser_CTP_hideBar.js
Normal file
@ -0,0 +1,98 @@
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
const gTestRoot = rootDir;
|
||||
const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
|
||||
|
||||
var gTestBrowser = null;
|
||||
var gNextTest = null;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
clearAllPluginPermissions();
|
||||
Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
|
||||
});
|
||||
Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
|
||||
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
gTestBrowser.addEventListener("load", pageLoad, true);
|
||||
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
||||
|
||||
prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_small.html");
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
gTestBrowser.removeEventListener("load", pageLoad, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish();
|
||||
}
|
||||
|
||||
function pageLoad() {
|
||||
// The plugin events are async dispatched and can come after the load event
|
||||
// This just allows the events to fire before we then go on to test the states
|
||||
executeSoon(gNextTest);
|
||||
}
|
||||
|
||||
function prepareTest(nextTest, url) {
|
||||
gNextTest = nextTest;
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
// Due to layout being async, "PluginBindAttached" may trigger later.
|
||||
// This wraps a function to force a layout flush, thus triggering it,
|
||||
// and schedules the function execution so they're definitely executed
|
||||
// afterwards.
|
||||
function runAfterPluginBindingAttached(func) {
|
||||
return function() {
|
||||
let doc = gTestBrowser.contentDocument;
|
||||
let elems = doc.getElementsByTagName('embed');
|
||||
if (elems.length < 1) {
|
||||
elems = doc.getElementsByTagName('object');
|
||||
}
|
||||
elems[0].clientTop;
|
||||
executeSoon(func);
|
||||
};
|
||||
}
|
||||
|
||||
// Test that the notification bar is getting dismissed when directly activating plugins
|
||||
// via the doorhanger.
|
||||
|
||||
function test1() {
|
||||
let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") !== null,
|
||||
test2,
|
||||
"Test 1, expected a notification bar for hidden plugins");
|
||||
}
|
||||
|
||||
function test2() {
|
||||
let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(notification, "Test 2, Should have a click-to-play notification");
|
||||
let plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 2, Found plugin in page");
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
|
||||
"Test 2, Plugin should be click-to-play");
|
||||
|
||||
// simulate "always allow"
|
||||
notification.reshow();
|
||||
PopupNotifications.panel.firstChild._primaryButton.click();
|
||||
|
||||
let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null,
|
||||
test3,
|
||||
"Test 2, expected the notification bar for hidden plugins to get dismissed");
|
||||
}
|
||||
|
||||
function test3() {
|
||||
let plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 3, Found plugin in page");
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
waitForCondition(() => objLoadingContent.activated, finishTest,
|
||||
"Test 3, Waited too long for plugin to activate");
|
||||
}
|
@ -860,7 +860,7 @@ function test26() {
|
||||
getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
|
||||
prepareTest(test27, gTestRoot + "plugin_small.html");
|
||||
},
|
||||
"Test 26, expected the plugin notification icon to be highlighted");
|
||||
"Test 26, expected to have a plugin notification bar");
|
||||
}
|
||||
|
||||
function test27() {
|
||||
@ -871,5 +871,5 @@ function test27() {
|
||||
|
||||
waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null,
|
||||
finishTest,
|
||||
"Test 27, expected the plugin notification icon to not be highlighted");
|
||||
"Test 27, expected to not have a plugin notification bar");
|
||||
}
|
||||
|
@ -76,6 +76,15 @@ GDBINIT_FILES := $(topsrcdir)/.gdbinit
|
||||
GDBINIT_DEST = $(FINAL_TARGET)
|
||||
INSTALL_TARGETS += GDBINIT
|
||||
|
||||
# Put a useful .lldbinit in the bin directory, to be picked up automatically
|
||||
# by LLDB when we debug executables using that directory as the current working
|
||||
# directory.
|
||||
# NOTE: Keep .lldbinit in the topsrcdir for people who run LLDB from the
|
||||
# topsrcdir rather than the bin directory.
|
||||
LLDBINIT_FILES := $(topsrcdir)/.lldbinit
|
||||
LLDBINIT_DEST = $(FINAL_TARGET)
|
||||
INSTALL_TARGETS += LLDBINIT
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# we install to _leaktest/
|
||||
|
@ -247,13 +247,6 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
|
||||
LD_IS_BFD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([LD_IS_BFD])
|
||||
|
||||
if test "$GNU_CC"; then
|
||||
if test -z "$DEVELOPER_OPTIONS"; then
|
||||
|
@ -777,7 +777,6 @@ endif
|
||||
else # !WINNT || GNU_CC
|
||||
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
endif # WINNT && !GNU_CC
|
||||
|
||||
ifdef ENABLE_STRIP
|
||||
@ -834,7 +833,6 @@ endif # MSVC with manifest tool
|
||||
else
|
||||
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
endif # WINNT && !GNU_CC
|
||||
|
||||
ifdef ENABLE_STRIP
|
||||
@ -937,7 +935,6 @@ else # ! DTRACE_LIB_DEPENDENT
|
||||
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
|
||||
endif # DTRACE_LIB_DEPENDENT
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
|
||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||
ifdef MSMANIFEST_TOOL
|
||||
@ -1712,7 +1709,3 @@ include $(topsrcdir)/config/makefiles/autotargets.mk
|
||||
ifneq ($(NULL),$(AUTO_DEPS))
|
||||
default all libs tools export:: $(AUTO_DEPS)
|
||||
endif
|
||||
|
||||
export:: $(GENERATED_FILES)
|
||||
|
||||
GARBAGE += $(GENERATED_FILES)
|
||||
|
@ -1826,6 +1826,7 @@ GK_ATOM(lineFrame, "LineFrame")
|
||||
GK_ATOM(listControlFrame,"ListControlFrame")
|
||||
GK_ATOM(menuFrame,"MenuFrame")
|
||||
GK_ATOM(menuPopupFrame,"MenuPopupFrame")
|
||||
GK_ATOM(numberControlFrame, "NumberControlFrame")
|
||||
GK_ATOM(objectFrame, "ObjectFrame")
|
||||
GK_ATOM(pageFrame, "PageFrame")
|
||||
GK_ATOM(pageBreakFrame, "PageBreakFrame")
|
||||
|
@ -154,6 +154,9 @@ WebGLContext::DepthMask(WebGLboolean b)
|
||||
void
|
||||
WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
const size_t buffersLength = buffers.Length();
|
||||
|
||||
if (buffersLength == 0) {
|
||||
|
@ -45,6 +45,7 @@ support-files =
|
||||
[test_bug493251.html]
|
||||
[test_bug502818.html]
|
||||
[test_bug508479.html]
|
||||
[test_bug822898.html]
|
||||
[test_bug517851.html]
|
||||
[test_bug534833.html]
|
||||
[test_bug545268.html]
|
||||
|
@ -298,6 +298,10 @@ const kEventConstructors = {
|
||||
return new PageTransitionEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
PointerEvent: { create: function (aName, aProps) {
|
||||
return new PointerEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
PopStateEvent: { create: function (aName, aProps) {
|
||||
return new PopStateEvent(aName, aProps);
|
||||
},
|
||||
|
359
content/events/test/test_bug822898.html
Normal file
359
content/events/test/test_bug822898.html
Normal file
@ -0,0 +1,359 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822898
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 822898</title>
|
||||
<script type="text/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=822898">Mozilla Bug 822898</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="subFrame"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.8">
|
||||
|
||||
/** Test for Bug 822898 - Pointer* Events **/
|
||||
|
||||
let tests = [], testTarget, parent, iframeBody, gOnPointerPropHandled;
|
||||
|
||||
function nextTest() {
|
||||
if (tests.length)
|
||||
SimpleTest.executeSoon(tests.shift());
|
||||
}
|
||||
|
||||
function random() {
|
||||
return Math.floor(Math.random() * 100);
|
||||
}
|
||||
|
||||
function createTestEventValue(name) {
|
||||
|
||||
let detail = random();
|
||||
let screenX = random();
|
||||
let screenY = random();
|
||||
let clientX = random();
|
||||
let clientY = random();
|
||||
let ctrlKey = random() % 2 ? true : false;
|
||||
let altKey = random() % 2 ? true : false;
|
||||
let shiftKey = random() % 2 ? true : false;
|
||||
let metaKey = random() % 2 ? true : false;
|
||||
let button = random();
|
||||
let pointerId = random();
|
||||
|
||||
return function() {
|
||||
let event = new PointerEvent("pointerdown", {
|
||||
bubbles: true, cancelable: true, view: window,
|
||||
detail: detail, screenX: screenX, screenY: screenY, clientX: clientX, clientY: clientY,
|
||||
ctrlKey: ctrlKey, altKey: altKey, shiftKey: shiftKey, metaKey: metaKey,
|
||||
button: button, relatedTarget: null, pointerId: pointerId
|
||||
});
|
||||
|
||||
|
||||
function check(ev) {
|
||||
is(ev.detail, detail, "Correct detail");
|
||||
is(ev.screenX, screenX, "Correct screenX");
|
||||
is(ev.screenY, screenY, "Correct screenY");
|
||||
is(ev.clientX, clientX, "Correct clientX");
|
||||
is(ev.clientY, clientY, "Correct clientY");
|
||||
is(ev.ctrlKey, ctrlKey, "Correct ctrlKey");
|
||||
is(ev.altKey, altKey, "Correct altKey");
|
||||
is(ev.shiftKey, shiftKey, "Correct shiftKey");
|
||||
is(ev.metaKey, metaKey, "Correct metaKey");
|
||||
is(ev.button, button, "Correct buttonArg");
|
||||
is(ev.pointerId, pointerId, "Correct pointerId");
|
||||
}
|
||||
|
||||
for each (let target in [document, window, testTarget, parent])
|
||||
target.addEventListener(name, check, false);
|
||||
|
||||
testTarget.dispatchEvent(event);
|
||||
|
||||
for each (let target in [document, window, testTarget, parent])
|
||||
target.removeEventListener(name, check, false);
|
||||
|
||||
|
||||
nextTest();
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultArgEvent(eventname) {
|
||||
return new PointerEvent(eventname, {
|
||||
bubbles: true, cancelable: true, view: window,
|
||||
detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
button: 0, relatedTarget: null, pointerId: 0
|
||||
});
|
||||
}
|
||||
|
||||
function testDefaultArg() {
|
||||
let event = getDefaultArgEvent("pointerdown");
|
||||
|
||||
testTarget.addEventListener("pointerdown", function(ev) {
|
||||
testTarget.removeEventListener("pointerdown", arguments.callee, false);
|
||||
is(ev.pointerId, 0, "Correct default pointerId");
|
||||
}, false);
|
||||
testTarget.dispatchEvent(event);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testStopPropagation() {
|
||||
let event = getDefaultArgEvent("pointerdown");
|
||||
|
||||
let unreachableListener = function () {
|
||||
ok(false, "Event should have been stopped");
|
||||
}
|
||||
|
||||
// Capturing phase
|
||||
let captured = false;
|
||||
parent.addEventListener("pointerdown", function() {
|
||||
parent.removeEventListener("pointerdown", arguments.callee, true);
|
||||
captured = true;
|
||||
}, true); // Capturing phase
|
||||
|
||||
// Bubbling phase
|
||||
parent.addEventListener("pointerdown", unreachableListener, false);
|
||||
|
||||
testTarget.addEventListener("pointerdown", function(ev) {
|
||||
testTarget.removeEventListener("pointerdown", arguments.callee, false);
|
||||
is(captured, true, "Event should have been captured");
|
||||
ev.stopPropagation();
|
||||
}, false);
|
||||
|
||||
testTarget.dispatchEvent(event);
|
||||
|
||||
parent.removeEventListener("pointerdown", unreachableListener, false);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testPreventDefault() {
|
||||
let event = getDefaultArgEvent("pointerdown");
|
||||
|
||||
parent.addEventListener("pointerdown", function(ev) {
|
||||
parent.removeEventListener("pointerdown", arguments.callee, false);
|
||||
is(ev.defaultPrevented, true, "preventDefault can be called");
|
||||
nextTest();
|
||||
}, false);
|
||||
|
||||
testTarget.addEventListener("pointerdown", function(ev) {
|
||||
testTarget.removeEventListener("pointerdown", arguments.callee, false);
|
||||
ev.preventDefault();
|
||||
}, false);
|
||||
|
||||
testTarget.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function testBlockPreventDefault() {
|
||||
let event = new PointerEvent("pointerdown", {
|
||||
bubbles: true, cancelable: false, view: window,
|
||||
detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
button: 0, relatedTarget: null, pointerId: 0, pointerType: "pen"
|
||||
});
|
||||
|
||||
parent.addEventListener("pointerdown", function(ev) {
|
||||
parent.removeEventListener("pointerdown", arguments.callee, false);
|
||||
is(ev.defaultPrevented, false, "aCancelableArg works");
|
||||
nextTest();
|
||||
}, false);
|
||||
|
||||
testTarget.addEventListener("pointerdown", function(ev) {
|
||||
testTarget.removeEventListener("pointerdown", arguments.callee, false);
|
||||
ev.preventDefault();
|
||||
}, false);
|
||||
|
||||
testTarget.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function testBlockBubbling() {
|
||||
let unreachableListener = function () {
|
||||
ok(false, "aCanBubble doesn't work");
|
||||
}
|
||||
|
||||
let event = new PointerEvent("pointerdown", {
|
||||
bubbles: false, cancelable: true, view: window,
|
||||
detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
button: 0, relatedTarget: null, pointerId: 0
|
||||
});
|
||||
|
||||
parent.addEventListener("pointerdown", unreachableListener, false);
|
||||
testTarget.dispatchEvent(event);
|
||||
parent.removeEventListener("pointerdown", unreachableListener, false);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testOnPointerProperty()
|
||||
{
|
||||
iframeBody.onpointerdown = function (e) { gOnPointerPropHandled["pointerdown"] = true; }
|
||||
iframeBody.onpointerup = function (e) { gOnPointerPropHandled["pointerup"] = true; }
|
||||
iframeBody.onpointermove = function (e) { gOnPointerPropHandled["pointermove"] = true; }
|
||||
iframeBody.onpointerout = function (e) { gOnPointerPropHandled["pointerout"] = true; }
|
||||
iframeBody.onpointerover = function (e) { gOnPointerPropHandled["pointerover"] = true; }
|
||||
iframeBody.onpointerenter = function (e) { gOnPointerPropHandled["pointerenter"] = true; }
|
||||
iframeBody.onpointerleave = function (e) { gOnPointerPropHandled["pointerleave"] = true; }
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerdown"));
|
||||
is(gOnPointerPropHandled['pointerdown'], true, "pointerdown property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerup"));
|
||||
is(gOnPointerPropHandled['pointerup'], true, "pointerup property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointermove"));
|
||||
is(gOnPointerPropHandled['pointermove'], true, "pointermove property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerout"));
|
||||
is(gOnPointerPropHandled['pointerout'], true, "pointerout property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerover"));
|
||||
is(gOnPointerPropHandled['pointerover'], true, "pointerover property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerenter"));
|
||||
is(gOnPointerPropHandled['pointerenter'], true, "pointerenter property is performed");
|
||||
|
||||
iframeBody.dispatchEvent(getDefaultArgEvent("pointerleave"));
|
||||
is(gOnPointerPropHandled['pointerleave'], true, "pointerleave property is performed");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testPointerEventCTORS()
|
||||
{
|
||||
// TODO: This should go to test_eventctors.html, when PointerEvents enabled by default
|
||||
var receivedEvent;
|
||||
iframeBody.addEventListener("hello", function(e) { receivedEvent = e; }, true);
|
||||
|
||||
var e;
|
||||
var ex = false;
|
||||
|
||||
try {
|
||||
e = new PointerEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "PointerEvent: First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new PointerEvent("hello");
|
||||
ok(e.type, "hello", "PointerEvent: Wrong event type!");
|
||||
ok(!e.isTrusted, "PointerEvent: Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "PointerEvent: Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "PointerEvent: Event shouldn't be cancelable!");
|
||||
iframeBody.dispatchEvent(e);
|
||||
is(receivedEvent, e, "PointerEvent: Wrong event!");
|
||||
|
||||
var PointerEventProps =
|
||||
[ { screenX: 0 },
|
||||
{ screenY: 0 },
|
||||
{ clientX: 0 },
|
||||
{ clientY: 0 },
|
||||
{ ctrlKey: false },
|
||||
{ shiftKey: false },
|
||||
{ altKey: false },
|
||||
{ metaKey: false },
|
||||
{ button: 0 },
|
||||
{ buttons: 0 },
|
||||
{ relatedTarget: null },
|
||||
{ pointerId: 0 },
|
||||
{ pointerType: "" }
|
||||
];
|
||||
|
||||
var testPointerProps =
|
||||
[
|
||||
{ screenX: 1 },
|
||||
{ screenY: 2 },
|
||||
{ clientX: 3 },
|
||||
{ clientY: 4 },
|
||||
{ ctrlKey: true },
|
||||
{ shiftKey: true },
|
||||
{ altKey: true },
|
||||
{ metaKey: true },
|
||||
{ button: 5 },
|
||||
{ buttons: 6 },
|
||||
{ relatedTarget: window },
|
||||
{ pointerId: 5 },
|
||||
{ pointerType: "mouse" }
|
||||
];
|
||||
|
||||
var defaultPointerEventValues = {};
|
||||
for (var i = 0; i < PointerEventProps.length; ++i) {
|
||||
for (prop in PointerEventProps[i]) {
|
||||
ok(prop in e, "PointerEvent: PointerEvent doesn't have property " + prop + "!");
|
||||
defaultPointerEventValues[prop] = PointerEventProps[i][prop];
|
||||
}
|
||||
}
|
||||
|
||||
while (testPointerProps.length) {
|
||||
var p = testPointerProps.shift();
|
||||
e = new PointerEvent("foo", p);
|
||||
for (var def in defaultPointerEventValues) {
|
||||
if (!(def in p)) {
|
||||
is(e[def], defaultPointerEventValues[def],
|
||||
"PointerEvent: Wrong default value for " + def + "!");
|
||||
} else {
|
||||
is(e[def], p[def], "PointerEvent: Wrong event init value for " + def + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
SpecialPowers.setBoolPref("dom.w3c_pointer_events.enabled", true); // Enable Pointer Events
|
||||
testTarget = document.getElementById("testTarget");
|
||||
parent = testTarget.parentNode;
|
||||
gOnPointerPropHandled = new Array;
|
||||
iframeBody = document.getElementById("subFrame").contentWindow.document.body;
|
||||
|
||||
tests.push(createTestEventValue("pointerdown"));
|
||||
tests.push(createTestEventValue("pointermove"));
|
||||
tests.push(createTestEventValue("pointerup"));
|
||||
|
||||
tests.push(testDefaultArg);
|
||||
tests.push(testStopPropagation);
|
||||
|
||||
tests.push(testPreventDefault);
|
||||
tests.push(testBlockPreventDefault);
|
||||
|
||||
tests.push(testBlockBubbling);
|
||||
tests.push(testOnPointerProperty());
|
||||
tests.push(testPointerEventCTORS());
|
||||
|
||||
tests.push(function() {
|
||||
clearPrefs();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function initPrefs()
|
||||
{
|
||||
SpecialPowers.setBoolPref("dom.w3c_pointer_events.enabled", true); // Enable Pointer Events
|
||||
}
|
||||
|
||||
function clearPrefs()
|
||||
{
|
||||
SpecialPowers.clearUserPref("dom.w3c_pointer_events.enabled"); // Disable Pointer Events
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
initPrefs();
|
||||
SimpleTest.executeSoon(runTests);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="parent">
|
||||
<span id="testTarget" style="border: 1px solid black;">testTarget</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -250,8 +250,6 @@ nsIFormControl::IsSingleLineTextControl(bool aExcludePassword, uint32_t aType)
|
||||
aType == NS_FORM_INPUT_SEARCH ||
|
||||
aType == NS_FORM_INPUT_TEL ||
|
||||
aType == NS_FORM_INPUT_URL ||
|
||||
// TODO: this is temporary until bug 635240 is fixed.
|
||||
aType == NS_FORM_INPUT_NUMBER ||
|
||||
// TODO: those are temporary until bug 773205 is fixed.
|
||||
aType == NS_FORM_INPUT_DATE ||
|
||||
aType == NS_FORM_INPUT_TIME ||
|
||||
|
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- In this case we're using reftest-wait to make sure the test doesn't
|
||||
get snapshotted before it's been focused. We're not testing
|
||||
invalidation so we don't need to listen for MozReftestInvalidate.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body onload="document.getElementsByTagName('input')[0].focus();">
|
||||
<input onfocus="document.documentElement.removeAttribute('class');"
|
||||
style="-moz-appearance: none;">
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
||||
|
26
content/html/content/reftests/autofocus/input-number.html
Normal file
26
content/html/content/reftests/autofocus/input-number.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- In this case we're using reftest-wait to make sure the test doesn't
|
||||
get snapshotted before it's been focused. We're not testing
|
||||
invalidation so we don't need to listen for MozReftestInvalidate.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
|
||||
function focusHandler() {
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute('class');
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="number" autofocus onfocus="focusHandler();"
|
||||
style="-moz-appearance: none;">
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,5 +1,6 @@
|
||||
needs-focus == input-load.html input-ref.html
|
||||
needs-focus == input-create.html input-ref.html
|
||||
fails-if(Android) needs-focus == input-number.html input-number-ref.html # bug 940764
|
||||
needs-focus == button-load.html button-ref.html
|
||||
needs-focus == button-create.html button-ref.html
|
||||
needs-focus == textarea-load.html textarea-ref.html
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsNumberControlFrame.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsIComponentManager.h"
|
||||
@ -2142,6 +2143,14 @@ HTMLInputElement::StepUp(int32_t n, uint8_t optional_argc)
|
||||
return ApplyStep(optional_argc ? n : 1);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::FlushFrames()
|
||||
{
|
||||
if (GetCurrentDoc()) {
|
||||
GetCurrentDoc()->FlushPendingNotifications(Flush_Frames);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::MozGetFileNameArray(nsTArray< nsString >& aArray)
|
||||
{
|
||||
@ -2233,7 +2242,7 @@ HTMLInputElement::MozSetFileNameArray(const PRUnichar** aFileNames, uint32_t aLe
|
||||
bool
|
||||
HTMLInputElement::MozIsTextField(bool aExcludePassword)
|
||||
{
|
||||
// TODO: temporary until bug 635240 and 773205 are fixed.
|
||||
// TODO: temporary until bug 773205 is fixed.
|
||||
if (IsExperimentalMobileType(mType)) {
|
||||
return false;
|
||||
}
|
||||
@ -2687,6 +2696,14 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue,
|
||||
SetValueChanged(true);
|
||||
}
|
||||
OnValueChanged(!mParserCreating);
|
||||
|
||||
if (mType == NS_FORM_INPUT_NUMBER) {
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
numberControlFrame->UpdateForValueChange(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call parent's SetAttr for color input so its control frame is notified
|
||||
@ -2952,9 +2969,41 @@ HTMLInputElement::SetCheckedInternal(bool aChecked, bool aNotify)
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::Blur(ErrorResult& aError)
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_NUMBER) {
|
||||
// Blur our anonymous text control, if we have one. (DOM 'change' event
|
||||
// firing and other things depend on this.)
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
|
||||
if (textControl) {
|
||||
textControl->Blur(aError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
nsGenericHTMLElement::Blur(aError);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::Focus(ErrorResult& aError)
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_NUMBER) {
|
||||
// Focus our anonymous text control, if we have one.
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
|
||||
if (textControl) {
|
||||
textControl->Focus(aError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mType != NS_FORM_INPUT_FILE) {
|
||||
nsGenericHTMLElement::Focus(aError);
|
||||
return;
|
||||
@ -3225,7 +3274,45 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
|
||||
|
||||
// We do this after calling the base class' PreHandleEvent so that
|
||||
// nsIContent::PreHandleEvent doesn't reset any change we make to mCanHandle.
|
||||
if (mType == NS_FORM_INPUT_NUMBER &&
|
||||
aVisitor.mEvent->mFlags.mIsTrusted &&
|
||||
aVisitor.mEvent->originalTarget != this) {
|
||||
// <input type=number> has an anonymous <input type=text> descendant. If
|
||||
// 'input' or 'change' events are fired at that text control then we need
|
||||
// to do some special handling here.
|
||||
HTMLInputElement* textControl = nullptr;
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
textControl = numberControlFrame->GetAnonTextControl();
|
||||
}
|
||||
if (textControl && aVisitor.mEvent->originalTarget == textControl) {
|
||||
if (aVisitor.mEvent->message == NS_FORM_INPUT) {
|
||||
// Propogate the anon text control's new value to our HTMLInputElement:
|
||||
numberControlFrame->HandlingInputEvent(true);
|
||||
nsAutoString value;
|
||||
textControl->GetValue(value);
|
||||
SetValueInternal(value, false, true);
|
||||
numberControlFrame->HandlingInputEvent(false);
|
||||
}
|
||||
else if (aVisitor.mEvent->message == NS_FORM_CHANGE) {
|
||||
// We cancel the DOM 'change' event that is fired for any change to our
|
||||
// anonymous text control since we fire our own 'change' events and
|
||||
// content shouldn't be seeing two 'change' events. Besides that we
|
||||
// (as a number) control have tighter restrictions on when our internal
|
||||
// value changes than our anon text control does, so in some cases
|
||||
// (if our text control's value doesn't parse as a number) we don't
|
||||
// want to fire a 'change' event at all.
|
||||
aVisitor.mCanHandle = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
@ -3421,7 +3508,8 @@ HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
// the click event handling, and allow cancellation of DOMActivate to cancel
|
||||
// the click.
|
||||
if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
!IsSingleLineTextControl(true)) {
|
||||
!IsSingleLineTextControl(true) &&
|
||||
mType != NS_FORM_INPUT_NUMBER) {
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
if (mouseEvent && mouseEvent->IsLeftClickEvent() &&
|
||||
!ShouldPreventDOMActivateDispatch(aVisitor.mEvent->originalTarget)) {
|
||||
@ -5516,7 +5604,8 @@ HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t*
|
||||
}
|
||||
|
||||
if (IsSingleLineTextControl(false) ||
|
||||
mType == NS_FORM_INPUT_RANGE) {
|
||||
mType == NS_FORM_INPUT_RANGE ||
|
||||
mType == NS_FORM_INPUT_NUMBER) {
|
||||
*aIsFocusable = true;
|
||||
return false;
|
||||
}
|
||||
@ -5727,7 +5816,7 @@ HTMLInputElement::PlaceholderApplies() const
|
||||
bool
|
||||
HTMLInputElement::DoesPatternApply() const
|
||||
{
|
||||
// TODO: temporary until bug 635240 and bug 773205 are fixed.
|
||||
// TODO: temporary until bug 773205 is fixed.
|
||||
if (IsExperimentalMobileType(mType)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
|
||||
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
|
||||
using nsGenericHTMLElement::Focus;
|
||||
virtual void Blur(ErrorResult& aError) MOZ_OVERRIDE;
|
||||
virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
|
||||
|
||||
// nsIDOMHTMLInputElement
|
||||
@ -574,6 +575,13 @@ public:
|
||||
void SetType(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
|
||||
if (aValue.Equals(NS_LITERAL_STRING("number"))) {
|
||||
// For NS_FORM_INPUT_NUMBER we rely on having frames to process key
|
||||
// events. Make sure we have them in case someone changes the type of
|
||||
// this element to "number" and then expects to be able to send key
|
||||
// events to it (type changes are rare, so not a big perf issue):
|
||||
FlushFrames();
|
||||
}
|
||||
}
|
||||
|
||||
// XPCOM GetDefaultValue() is OK
|
||||
@ -1088,10 +1096,14 @@ protected:
|
||||
*/
|
||||
static bool IsExperimentalMobileType(uint8_t aType)
|
||||
{
|
||||
return aType == NS_FORM_INPUT_NUMBER || aType == NS_FORM_INPUT_DATE ||
|
||||
aType == NS_FORM_INPUT_TIME;
|
||||
return aType == NS_FORM_INPUT_DATE || aType == NS_FORM_INPUT_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the layout frame tree to make sure we have up-to-date frames.
|
||||
*/
|
||||
void FlushFrames();
|
||||
|
||||
/**
|
||||
* Returns true if the element should prevent dispatching another DOMActivate.
|
||||
* This is used in situations where the anonymous subtree should already have
|
||||
@ -1243,7 +1255,8 @@ private:
|
||||
|
||||
static bool MayFireChangeOnBlur(uint8_t aType) {
|
||||
return IsSingleLineTextControl(false, aType) ||
|
||||
aType == NS_FORM_INPUT_RANGE;
|
||||
aType == NS_FORM_INPUT_RANGE ||
|
||||
aType == NS_FORM_INPUT_NUMBER;
|
||||
}
|
||||
|
||||
struct nsFilePickerFilter {
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
SetHTMLIntAttr(nsGkAtoms::tabindex, aTabIndex, aError);
|
||||
}
|
||||
virtual void Focus(mozilla::ErrorResult& aError);
|
||||
void Blur(mozilla::ErrorResult& aError);
|
||||
virtual void Blur(mozilla::ErrorResult& aError);
|
||||
void GetAccessKey(nsString& aAccessKey)
|
||||
{
|
||||
GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
|
||||
|
@ -29,6 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
|
||||
<input type="reset" id="input_reset" onchange="++NonTextInputChange[3];"></input>
|
||||
<input type="radio" id="input_radio" onchange="++NonTextInputChange[4];"></input>
|
||||
<input type="checkbox" id="input_checkbox" onchange="++NonTextInputChange[5];"></input>
|
||||
<input type="number" id="input_number" onchange="++numberChange;"></input>
|
||||
<input type="range" id="input_range" onchange="++rangeChange;"></input>
|
||||
|
||||
</div>
|
||||
@ -45,6 +46,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
|
||||
var NonTextInputTypes = ["button", "submit", "image", "reset", "radio", "checkbox"];
|
||||
var NonTextInputChange = [0, 0, 0, 0, 0, 0];
|
||||
|
||||
var numberChange = 0;
|
||||
var rangeChange = 0;
|
||||
|
||||
var blurTestCalled = false; //Sentinel to prevent infinite loop.
|
||||
@ -164,6 +166,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
|
||||
}
|
||||
}
|
||||
|
||||
// Special case type=number
|
||||
var number = document.getElementById("input_number");
|
||||
number.focus();
|
||||
synthesizeKey("a", {});
|
||||
number.blur();
|
||||
is(numberChange, 0, "Change event shouldn't be dispatched on number input element for key changes that don't change its value");
|
||||
number.value = "";
|
||||
number.focus();
|
||||
synthesizeKey("1", {});
|
||||
is(numberChange, 0, "Change event shouldn't be dispatched on number input element for keyboard input until it is looses focus");
|
||||
number.blur();
|
||||
is(numberChange, 1, "Change event should be dispatched on number input element on blur");
|
||||
|
||||
// Special case type=range
|
||||
var range = document.getElementById("input_range");
|
||||
range.focus();
|
||||
|
@ -4,7 +4,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'nsMathMLElement.cpp',
|
||||
'nsMathMLElementFactory.cpp',
|
||||
]
|
||||
|
@ -8,10 +8,6 @@ EXPORTS += [
|
||||
'MP4Decoder.h',
|
||||
'MP4Reader.h',
|
||||
'PlatformDecoderModule.h',
|
||||
'wmf/MFTDecoder.h',
|
||||
'wmf/WMFAudioDecoder.h',
|
||||
'wmf/WMFDecoderModule.h',
|
||||
'wmf/WMFVideoDecoder.h',
|
||||
]
|
||||
|
||||
EXPORTS.mp4_demuxer += [
|
||||
@ -53,6 +49,16 @@ SOURCES += [
|
||||
'MP4Decoder.cpp',
|
||||
'MP4Reader.cpp',
|
||||
'PlatformDecoderModule.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WMF']:
|
||||
EXPORTS += [
|
||||
'wmf/MFTDecoder.h',
|
||||
'wmf/WMFAudioDecoder.h',
|
||||
'wmf/WMFDecoderModule.h',
|
||||
'wmf/WMFVideoDecoder.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'wmf/MFTDecoder.cpp',
|
||||
'wmf/WMFAudioDecoder.cpp',
|
||||
'wmf/WMFDecoderModule.cpp',
|
||||
|
@ -1779,7 +1779,7 @@ nsXULElement::GetWindowWidget()
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
|
||||
// only top level chrome documents can set the titlebar color
|
||||
if (doc->IsRootDisplayDocument()) {
|
||||
if (doc && doc->IsRootDisplayDocument()) {
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
|
||||
if (baseWindow) {
|
||||
|
@ -77,10 +77,12 @@ ActivityProxy.prototype = {
|
||||
debug("FireSuccess");
|
||||
Services.DOMRequest.fireSuccess(this.activity,
|
||||
ObjectWrapper.wrap(msg.result, this.window));
|
||||
Services.obs.notifyObservers(null, "Activity:Success", null);
|
||||
break;
|
||||
case "Activity:FireError":
|
||||
debug("FireError");
|
||||
Services.DOMRequest.fireError(this.activity, msg.error);
|
||||
Services.obs.notifyObservers(null, "Activity:Error", null);
|
||||
break;
|
||||
}
|
||||
// We can only get one FireSuccess / FireError message, so cleanup as soon as possible.
|
||||
|
@ -63,8 +63,10 @@ const ContentPanning = {
|
||||
|
||||
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
|
||||
addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
|
||||
addEventListener("visibilitychange", this._recvVisibilityChange.bind(this));
|
||||
addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
|
||||
Services.obs.addObserver(this, "BEC:ShownModalPrompt", false);
|
||||
Services.obs.addObserver(this, "Activity:Success", false);
|
||||
Services.obs.addObserver(this, "Activity:Error", false);
|
||||
},
|
||||
|
||||
handleEvent: function cp_handleEvent(evt) {
|
||||
@ -461,8 +463,10 @@ const ContentPanning = {
|
||||
|
||||
_resetHover: function cp_resetHover() {
|
||||
const kStateHover = 0x00000004;
|
||||
try {
|
||||
let element = content.document.createElement('foo');
|
||||
this._domUtils.setContentState(element, kStateHover);
|
||||
} catch(e) {}
|
||||
},
|
||||
|
||||
_setActive: function cp_setActive(elt) {
|
||||
@ -546,7 +550,7 @@ const ContentPanning = {
|
||||
}
|
||||
},
|
||||
|
||||
_recvVisibilityChange: function(evt) {
|
||||
_handleVisibilityChange: function(evt) {
|
||||
if (!evt.target.hidden)
|
||||
return;
|
||||
|
||||
|
@ -4,8 +4,16 @@
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
EncodingUtils.$(OBJ_SUFFIX): labelsencodings.properties.h
|
||||
FallbackEncoding.$(OBJ_SUFFIX): localesfallbacks.properties.h
|
||||
|
||||
PROPS2ARRAYS = $(topsrcdir)/intl/locale/src/props2arrays.py
|
||||
labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties
|
||||
$(PYTHON) $^ $@
|
||||
localesfallbacks.properties.h: $(PROPS2ARRAYS) localesfallbacks.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
||||
GARBAGE += \
|
||||
labelsencodings.properties.h \
|
||||
localesfallbacks.properties.h \
|
||||
$(NULL)
|
||||
|
@ -30,7 +30,3 @@ LOCAL_INCLUDES += [
|
||||
'/intl/locale/src',
|
||||
]
|
||||
|
||||
GENERATED_FILES += [
|
||||
'labelsencodings.properties.h',
|
||||
'localesfallbacks.properties.h',
|
||||
]
|
||||
|
@ -574,20 +574,23 @@ AudioManager::SetFmRadioAudioEnabled(bool aFmRadioAudioEnabled)
|
||||
|
||||
NS_IMETHODIMP
|
||||
AudioManager::SetAudioChannelVolume(int32_t aChannel, int32_t aIndex) {
|
||||
status_t status;
|
||||
nsresult status;
|
||||
|
||||
switch (aChannel) {
|
||||
case AUDIO_CHANNEL_CONTENT:
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_MUSIC, aIndex);
|
||||
status += SetStreamVolumeIndex(AUDIO_STREAM_SYSTEM, aIndex);
|
||||
// sync FMRadio's volume with content channel.
|
||||
if (IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
|
||||
status += SetStreamVolumeIndex(AUDIO_STREAM_FM, aIndex);
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_FM, aIndex);
|
||||
NS_ENSURE_SUCCESS(status, status);
|
||||
}
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_MUSIC, aIndex);
|
||||
NS_ENSURE_SUCCESS(status, status);
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_SYSTEM, aIndex);
|
||||
break;
|
||||
case AUDIO_CHANNEL_NOTIFICATION:
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_NOTIFICATION, aIndex);
|
||||
status += SetStreamVolumeIndex(AUDIO_STREAM_RING, aIndex);
|
||||
NS_ENSURE_SUCCESS(status, status);
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_RING, aIndex);
|
||||
break;
|
||||
case AUDIO_CHANNEL_ALARM:
|
||||
status = SetStreamVolumeIndex(AUDIO_STREAM_ALARM, aIndex);
|
||||
@ -599,7 +602,7 @@ AudioManager::SetAudioChannelVolume(int32_t aChannel, int32_t aIndex) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -664,17 +667,19 @@ AudioManager::GetMaxAudioChannelVolume(int32_t aChannel, int32_t* aMaxIndex) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
nsresult
|
||||
AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
|
||||
if (aIndex < 0 || aIndex > sMaxStreamVolumeTbl[aStream]) {
|
||||
return BAD_VALUE;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mCurrentStreamVolumeTbl[aStream] = aIndex;
|
||||
status_t status;
|
||||
#if ANDROID_VERSION < 17
|
||||
return AudioSystem::setStreamVolumeIndex(
|
||||
status = AudioSystem::setStreamVolumeIndex(
|
||||
static_cast<audio_stream_type_t>(aStream),
|
||||
aIndex);
|
||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||
#else
|
||||
int device = 0;
|
||||
|
||||
@ -685,13 +690,18 @@ AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
|
||||
}
|
||||
|
||||
if (device != 0) {
|
||||
return AudioSystem::setStreamVolumeIndex(
|
||||
status = AudioSystem::setStreamVolumeIndex(
|
||||
static_cast<audio_stream_type_t>(aStream),
|
||||
aIndex,
|
||||
device);
|
||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
status_t status = AudioSystem::setStreamVolumeIndex(
|
||||
status = AudioSystem::setStreamVolumeIndex(
|
||||
static_cast<audio_stream_type_t>(aStream),
|
||||
aIndex,
|
||||
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
|
||||
status += AudioSystem::setStreamVolumeIndex(
|
||||
static_cast<audio_stream_type_t>(aStream),
|
||||
aIndex,
|
||||
AUDIO_DEVICE_OUT_SPEAKER);
|
||||
@ -707,21 +717,21 @@ AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
|
||||
static_cast<audio_stream_type_t>(aStream),
|
||||
aIndex,
|
||||
AUDIO_DEVICE_OUT_EARPIECE);
|
||||
return status;
|
||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
status_t
|
||||
nsresult
|
||||
AudioManager::GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex) {
|
||||
if (!aIndex) {
|
||||
return BAD_VALUE;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
|
||||
return BAD_VALUE;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*aIndex = mCurrentStreamVolumeTbl[aStream];
|
||||
|
||||
return NO_ERROR;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ protected:
|
||||
int32_t mPhoneState;
|
||||
int mCurrentStreamVolumeTbl[AUDIO_STREAM_CNT];
|
||||
|
||||
android::status_t SetStreamVolumeIndex(int32_t aStream, int32_t aIndex);
|
||||
android::status_t GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex);
|
||||
nsresult SetStreamVolumeIndex(int32_t aStream, int32_t aIndex);
|
||||
nsresult GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex);
|
||||
|
||||
private:
|
||||
nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
|
||||
|
@ -405,6 +405,7 @@ var interfaceNamesInGlobalScope =
|
||||
"PhoneNumberService",
|
||||
"Plugin",
|
||||
"PluginArray",
|
||||
{name: "PointerEvent", pref: "dom.w3c_pointer_events.enabled"},
|
||||
"PopStateEvent",
|
||||
"PopupBlockedEvent",
|
||||
"ProcessingInstruction",
|
||||
|
@ -79,3 +79,5 @@ endif
|
||||
|
||||
PremultiplyTables.h: $(srcdir)/genTables.py
|
||||
$(PYTHON) $(srcdir)/genTables.py
|
||||
|
||||
gfxUtils.$(OBJ_SUFFIX): PremultiplyTables.h
|
||||
|
@ -279,7 +279,3 @@ LIBRARY_NAME = 'thebes'
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'PremultiplyTables.h',
|
||||
]
|
||||
|
@ -19,8 +19,14 @@ LOCAL_INCLUDES = \
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
nsCharsetAlias.$(OBJ_SUFFIX): charsetalias.properties.h
|
||||
|
||||
charsetalias.properties.h: props2arrays.py charsetalias.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
||||
GARBAGE += \
|
||||
charsetalias.properties.h \
|
||||
$(NULL)
|
||||
|
||||
libs::
|
||||
$(INSTALL) $(EXPORT_RESOURCE) $(DIST)/bin/res
|
||||
|
@ -34,7 +34,3 @@ EXTRA_JS_MODULES += [
|
||||
MSVC_ENABLE_PGO = True
|
||||
|
||||
FINAL_LIBRARY = 'i18n'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'charsetalias.properties.h',
|
||||
]
|
||||
|
@ -7,5 +7,11 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(srcdir)/..
|
||||
|
||||
nsOS2Charset.$(OBJ_SUFFIX): os2charset.properties.h
|
||||
|
||||
os2charset.properties.h: $(srcdir)/../props2arrays.py os2charset.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
||||
GARBAGE += \
|
||||
os2charset.properties.h \
|
||||
$(NULL)
|
||||
|
@ -12,7 +12,3 @@ SOURCES += [
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'i18n'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'os2charset.properties.h',
|
||||
]
|
||||
|
@ -16,5 +16,11 @@ endif
|
||||
|
||||
DEFINES += -DOSTYPE=\"$(OS_CONFIG)\"
|
||||
|
||||
nsUNIXCharset.$(OBJ_SUFFIX): unixcharset.properties.h
|
||||
|
||||
unixcharset.properties.h: $(srcdir)/../props2arrays.py unixcharset.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
||||
GARBAGE += \
|
||||
unixcharset.properties.h \
|
||||
$(NULL)
|
||||
|
@ -20,7 +20,3 @@ else:
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'i18n'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'unixcharset.properties.h',
|
||||
]
|
||||
|
@ -7,5 +7,11 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(srcdir)/..
|
||||
|
||||
nsWinCharset.$(OBJ_SUFFIX): wincharset.properties.h
|
||||
|
||||
wincharset.properties.h: $(srcdir)/../props2arrays.py wincharset.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
||||
GARBAGE += \
|
||||
wincharset.properties.h \
|
||||
$(NULL)
|
||||
|
@ -12,7 +12,3 @@ SOURCES += [
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'i18n'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'wincharset.properties.h',
|
||||
]
|
||||
|
@ -606,6 +606,8 @@ ifdef MOZ_ETW
|
||||
ETWProvider.h ETWProvider.rc ETWProvider.mof: ETWProvider.man
|
||||
$(MC) -um -mof $^
|
||||
|
||||
Probes.$(OBJ_SUFFIX): ETWProvider.h
|
||||
|
||||
ETWProvider.res: ETWProvider.rc
|
||||
$(RC) -r -i "$(SDKDIR)Include" $^
|
||||
|
||||
|
@ -247,13 +247,6 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
|
||||
LD_IS_BFD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([LD_IS_BFD])
|
||||
|
||||
if test "$GNU_CC"; then
|
||||
if test -z "$DEVELOPER_OPTIONS"; then
|
||||
|
@ -777,7 +777,6 @@ endif
|
||||
else # !WINNT || GNU_CC
|
||||
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
endif # WINNT && !GNU_CC
|
||||
|
||||
ifdef ENABLE_STRIP
|
||||
@ -834,7 +833,6 @@ endif # MSVC with manifest tool
|
||||
else
|
||||
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
endif # WINNT && !GNU_CC
|
||||
|
||||
ifdef ENABLE_STRIP
|
||||
@ -937,7 +935,6 @@ else # ! DTRACE_LIB_DEPENDENT
|
||||
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
|
||||
endif # DTRACE_LIB_DEPENDENT
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
@$(call LOCAL_CHECKS,$@)
|
||||
|
||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||
ifdef MSMANIFEST_TOOL
|
||||
@ -1712,7 +1709,3 @@ include $(topsrcdir)/config/makefiles/autotargets.mk
|
||||
ifneq ($(NULL),$(AUTO_DEPS))
|
||||
default all libs tools export:: $(AUTO_DEPS)
|
||||
endif
|
||||
|
||||
export:: $(GENERATED_FILES)
|
||||
|
||||
GARBAGE += $(GENERATED_FILES)
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
LIBRARY_NAME = 'editline'
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'editline.c',
|
||||
'sysunix.c',
|
||||
]
|
||||
|
@ -434,7 +434,7 @@ class RelocatablePtr : public BarrieredPtr<T>
|
||||
|
||||
~RelocatablePtr() {
|
||||
if (this->value)
|
||||
relocate(this->value->runtimeFromAnyThread());
|
||||
relocate();
|
||||
}
|
||||
|
||||
RelocatablePtr<T> &operator=(T *v) {
|
||||
@ -444,9 +444,8 @@ class RelocatablePtr : public BarrieredPtr<T>
|
||||
this->value = v;
|
||||
post();
|
||||
} else if (this->value) {
|
||||
JSRuntime *rt = this->value->runtimeFromAnyThread();
|
||||
relocate();
|
||||
this->value = v;
|
||||
relocate(rt);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -458,9 +457,8 @@ class RelocatablePtr : public BarrieredPtr<T>
|
||||
this->value = v.value;
|
||||
post();
|
||||
} else if (this->value) {
|
||||
JSRuntime *rt = this->value->runtimeFromAnyThread();
|
||||
relocate();
|
||||
this->value = v;
|
||||
relocate(rt);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -473,8 +471,9 @@ class RelocatablePtr : public BarrieredPtr<T>
|
||||
#endif
|
||||
}
|
||||
|
||||
void relocate(JSRuntime *rt) {
|
||||
void relocate() {
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JS_ASSERT(this->value);
|
||||
T::writeBarrierPostRemove(this->value, &this->value);
|
||||
#endif
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment)
|
||||
void *p = nullptr;
|
||||
while (!p) {
|
||||
/*
|
||||
* Over-allocate in order to map a memory region that is
|
||||
* definitely large enough then deallocate and allocate again the
|
||||
* correct sizee, within the over-sized mapping.
|
||||
* Over-allocate in order to map a memory region that is definitely
|
||||
* large enough, then deallocate and allocate again the correct size,
|
||||
* within the over-sized mapping.
|
||||
*
|
||||
* Since we're going to unmap the whole thing anyway, the first
|
||||
* mapping doesn't have to commit pages.
|
||||
@ -63,7 +63,7 @@ gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment)
|
||||
p = VirtualAlloc(nullptr, size * 2, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
void *chunkStart = (void *)(uintptr_t(p) + (alignment - (uintptr_t(p) % alignment)));
|
||||
void *chunkStart = (void *)AlignBytes(uintptr_t(p), alignment);
|
||||
UnmapPages(rt, p, size * 2);
|
||||
p = VirtualAlloc(chunkStart, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
@ -372,7 +372,7 @@ gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment)
|
||||
uintptr_t offset = uintptr_t(region) % alignment;
|
||||
JS_ASSERT(offset < reqSize - size);
|
||||
|
||||
void *front = (void *)(uintptr_t(region) + (alignment - offset));
|
||||
void *front = (void *)AlignBytes(uintptr_t(region), alignment);
|
||||
void *end = (void *)(uintptr_t(front) + size);
|
||||
if (front != region)
|
||||
JS_ALWAYS_TRUE(0 == munmap(region, alignment - offset));
|
||||
|
@ -420,14 +420,10 @@ class StoreBuffer
|
||||
}
|
||||
void removeRelocatableValue(JS::Value *valuep) {
|
||||
ValueEdge edge(valuep);
|
||||
if (!edge.inRememberedSet(nursery_))
|
||||
return;
|
||||
bufferRelocVal.unput(edge);
|
||||
}
|
||||
void removeRelocatableCell(Cell **cellp) {
|
||||
CellPtrEdge edge(cellp);
|
||||
if (!edge.inRememberedSet(nursery_))
|
||||
return;
|
||||
bufferRelocCell.unput(edge);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
PROGRAM = 'gdb-tests'
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'gdb-tests.cpp',
|
||||
'tests/test-jsid.cpp',
|
||||
'tests/test-JSObject.cpp',
|
||||
|
47
js/src/jit-test/tests/ion/bug939868-2.js
Normal file
47
js/src/jit-test/tests/ion/bug939868-2.js
Normal file
@ -0,0 +1,47 @@
|
||||
function f(x,y,z) {
|
||||
var z;
|
||||
if (x) {
|
||||
if (y) {
|
||||
z = 0xfffffff;
|
||||
} else {
|
||||
z = 0xfffffff;
|
||||
}
|
||||
assertFloat32(z, false);
|
||||
} else {
|
||||
z = Math.fround(z);
|
||||
assertFloat32(z, true);
|
||||
}
|
||||
assertFloat32(z, false);
|
||||
return z;
|
||||
}
|
||||
|
||||
function g(x,y,z) {
|
||||
var z;
|
||||
if (x) {
|
||||
if (y) {
|
||||
z = 3;
|
||||
} else {
|
||||
z = 6;
|
||||
}
|
||||
assertFloat32(z, false);
|
||||
} else {
|
||||
z = Math.fround(z);
|
||||
assertFloat32(z, true);
|
||||
}
|
||||
assertFloat32(z, true);
|
||||
return z;
|
||||
}
|
||||
|
||||
setJitCompilerOption("ion.usecount.trigger", 50);
|
||||
|
||||
for (var n = 100; n--; ) {
|
||||
assertEq(f(0,1,2), 2);
|
||||
assertEq(f(0,0,2), 2);
|
||||
assertEq(f(1,0,2), 0xfffffff);
|
||||
assertEq(f(1,1,2), 0xfffffff);
|
||||
|
||||
assertEq(g(0,1,2), 2);
|
||||
assertEq(g(0,0,2), 2);
|
||||
assertEq(g(1,0,2), 6);
|
||||
assertEq(g(1,1,2), 3);
|
||||
}
|
3
js/src/jit-test/tests/ion/bug939868.js
Normal file
3
js/src/jit-test/tests/ion/bug939868.js
Normal file
@ -0,0 +1,3 @@
|
||||
function f(x, y) { return x || Math.fround(y); }
|
||||
assertEq(f(0, 0), 0);
|
||||
assertEq(f(0xfffffff, 0), 0xfffffff);
|
15
js/src/jit-test/tests/ion/bug940846.js
Normal file
15
js/src/jit-test/tests/ion/bug940846.js
Normal file
@ -0,0 +1,15 @@
|
||||
function a(f, i) {
|
||||
results = []
|
||||
for (var k = 0; k < 10; ++k) {
|
||||
gc();
|
||||
try {
|
||||
results.push(f(i[k]));
|
||||
} catch (e) {
|
||||
results.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
g = (function(x, y) {
|
||||
return Math.fround((x ? Math.f : m0) ? w : Math.fround())
|
||||
})
|
||||
a(g, [Number.MAX_VALUE])
|
@ -452,7 +452,7 @@ GuessPhiType(MPhi *phi)
|
||||
}
|
||||
if (type == MIRType_None) {
|
||||
type = in->type();
|
||||
if (in->isConstant())
|
||||
if (in->canProduceFloat32())
|
||||
convertibleToFloat32 = true;
|
||||
continue;
|
||||
}
|
||||
@ -461,17 +461,14 @@ GuessPhiType(MPhi *phi)
|
||||
if (in->resultTypeSet() && in->resultTypeSet()->empty())
|
||||
continue;
|
||||
|
||||
if (IsFloatType(type) && IsFloatType(in->type())) {
|
||||
// Specialize phis with int32 and float32 operands as float32.
|
||||
type = MIRType_Float32;
|
||||
} else if (convertibleToFloat32 && in->type() == MIRType_Float32) {
|
||||
// If we only saw constants before and encounter a Float32 value, promote previous
|
||||
// constants to Float32
|
||||
if (convertibleToFloat32 && in->type() == MIRType_Float32) {
|
||||
// If we only saw definitions that can be converted into Float32 before and
|
||||
// encounter a Float32 value, promote previous values to Float32
|
||||
type = MIRType_Float32;
|
||||
} else if (IsNumberType(type) && IsNumberType(in->type())) {
|
||||
// Specialize phis with int32 and double operands as double.
|
||||
type = MIRType_Double;
|
||||
convertibleToFloat32 &= in->isConstant();
|
||||
convertibleToFloat32 &= in->canProduceFloat32();
|
||||
} else {
|
||||
return MIRType_Value;
|
||||
}
|
||||
@ -510,8 +507,10 @@ TypeAnalyzer::propagateSpecialization(MPhi *phi)
|
||||
continue;
|
||||
}
|
||||
if (use->type() != phi->type()) {
|
||||
// Specialize phis with int32 and float operands as floats.
|
||||
if (IsFloatType(use->type()) && IsFloatType(phi->type())) {
|
||||
// Specialize phis with int32 that can be converted to float and float operands as floats.
|
||||
if ((use->type() == MIRType_Int32 && use->canProduceFloat32() && phi->type() == MIRType_Float32) ||
|
||||
(phi->type() == MIRType_Int32 && phi->canProduceFloat32() && use->type() == MIRType_Float32))
|
||||
{
|
||||
if (!respecialize(use, MIRType_Float32))
|
||||
return false;
|
||||
continue;
|
||||
|
@ -846,9 +846,7 @@ jit::MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
|
||||
if (newTypeSet && newTypeSet->empty())
|
||||
return;
|
||||
if (newType != *ptype) {
|
||||
if (IsFloatType(newType) && IsFloatType(*ptype)) {
|
||||
*ptype = MIRType_Float32;
|
||||
} else if (IsNumberType(newType) && IsNumberType(*ptype)) {
|
||||
if (IsNumberType(newType) && IsNumberType(*ptype)) {
|
||||
*ptype = MIRType_Double;
|
||||
} else if (*ptype != MIRType_Value) {
|
||||
if (!*ptypeSet)
|
||||
|
@ -5789,7 +5789,7 @@ class MArrayPopShift
|
||||
// Array.prototype.push on a dense array. Returns the new array length.
|
||||
class MArrayPush
|
||||
: public MBinaryInstruction,
|
||||
public SingleObjectPolicy
|
||||
public MixPolicy<SingleObjectPolicy, NoFloatPolicy<1> >
|
||||
{
|
||||
MArrayPush(MDefinition *object, MDefinition *value)
|
||||
: MBinaryInstruction(object, value)
|
||||
|
@ -34,6 +34,7 @@ UNIFIED_SOURCES += [
|
||||
'testGCExactRooting.cpp',
|
||||
'testGCFinalizeCallback.cpp',
|
||||
'testGCOutOfMemory.cpp',
|
||||
'testGCStoreBufferRemoval.cpp',
|
||||
'testHashTable.cpp',
|
||||
'testHashTableInit.cpp',
|
||||
'testIndexToString.cpp',
|
||||
|
114
js/src/jsapi-tests/testGCStoreBufferRemoval.cpp
Normal file
114
js/src/jsapi-tests/testGCStoreBufferRemoval.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using namespace JS;
|
||||
using namespace js;
|
||||
|
||||
BEGIN_TEST(testGCStoreBufferRemoval)
|
||||
{
|
||||
// Sanity check - objects start in the nursery and then become tenured.
|
||||
JS_GC(cx->runtime());
|
||||
JS::RootedObject obj(cx, NurseryObject());
|
||||
CHECK(js::gc::IsInsideNursery(rt, obj.get()));
|
||||
JS_GC(cx->runtime());
|
||||
CHECK(!js::gc::IsInsideNursery(rt, obj.get()));
|
||||
JS::RootedObject tenuredObject(cx, obj);
|
||||
|
||||
// Test removal of store buffer entries added by RelocatablePtr<T>.
|
||||
{
|
||||
JSObject *badObject = reinterpret_cast<JSObject*>(1);
|
||||
JSObject *punnedPtr = nullptr;
|
||||
RelocatablePtrObject* relocPtr =
|
||||
reinterpret_cast<RelocatablePtrObject*>(&punnedPtr);
|
||||
new (relocPtr) RelocatablePtrObject;
|
||||
*relocPtr = NurseryObject();
|
||||
relocPtr->~RelocatablePtrObject();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (relocPtr) RelocatablePtrObject;
|
||||
*relocPtr = NurseryObject();
|
||||
*relocPtr = tenuredObject;
|
||||
relocPtr->~RelocatablePtrObject();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (relocPtr) RelocatablePtrObject;
|
||||
*relocPtr = NurseryObject();
|
||||
*relocPtr = nullptr;
|
||||
relocPtr->~RelocatablePtrObject();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
}
|
||||
|
||||
// Test removal of store buffer entries added by RelocatableValue.
|
||||
{
|
||||
Value punnedValue;
|
||||
RelocatableValue *relocValue = reinterpret_cast<RelocatableValue*>(&punnedValue);
|
||||
new (relocValue) RelocatableValue;
|
||||
*relocValue = ObjectValue(*NurseryObject());
|
||||
relocValue->~RelocatableValue();
|
||||
punnedValue = ObjectValueCrashOnTouch();
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (relocValue) RelocatableValue;
|
||||
*relocValue = ObjectValue(*NurseryObject());
|
||||
*relocValue = ObjectValue(*tenuredObject);
|
||||
relocValue->~RelocatableValue();
|
||||
punnedValue = ObjectValueCrashOnTouch();
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (relocValue) RelocatableValue;
|
||||
*relocValue = ObjectValue(*NurseryObject());
|
||||
*relocValue = NullValue();
|
||||
relocValue->~RelocatableValue();
|
||||
punnedValue = ObjectValueCrashOnTouch();
|
||||
JS_GC(cx->runtime());
|
||||
}
|
||||
|
||||
// Test removal of store buffer entries added by Heap<T>.
|
||||
{
|
||||
JSObject *badObject = reinterpret_cast<JSObject*>(1);
|
||||
JSObject *punnedPtr = nullptr;
|
||||
Heap<JSObject*>* heapPtr =
|
||||
reinterpret_cast<Heap<JSObject*>*>(&punnedPtr);
|
||||
new (heapPtr) Heap<JSObject*>;
|
||||
*heapPtr = NurseryObject();
|
||||
heapPtr->~Heap<JSObject*>();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (heapPtr) Heap<JSObject*>;
|
||||
*heapPtr = NurseryObject();
|
||||
*heapPtr = tenuredObject;
|
||||
heapPtr->~Heap<JSObject*>();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
new (heapPtr) Heap<JSObject*>;
|
||||
*heapPtr = NurseryObject();
|
||||
*heapPtr = nullptr;
|
||||
heapPtr->~Heap<JSObject*>();
|
||||
punnedPtr = badObject;
|
||||
JS_GC(cx->runtime());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *NurseryObject()
|
||||
{
|
||||
return JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
}
|
||||
END_TEST(testGCStoreBufferRemoval)
|
||||
|
||||
#endif
|
@ -391,8 +391,3 @@ if CONFIG['JS_SHARED_LIBRARY']:
|
||||
FORCE_SHARED_LIB = True
|
||||
|
||||
FORCE_STATIC_LIB = True
|
||||
|
||||
if CONFIG['MOZ_ETW']:
|
||||
GENERATED_FILES = [
|
||||
'ETWProvider.h',
|
||||
]
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
PROGRAM = CONFIG['JS_SHELL_NAME']
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'js.cpp',
|
||||
'jsheaptools.cpp',
|
||||
'jsoptparse.cpp',
|
||||
|
@ -4,8 +4,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# These files cannot be built in unified mode because they rely on plarena.h
|
||||
# and they want to force NSPR logging.
|
||||
SOURCES += [
|
||||
'mozJSComponentLoader.cpp',
|
||||
'mozJSLoaderUtils.cpp',
|
||||
|
@ -63,6 +63,10 @@ ifdef MOZ_JSDEBUGGER
|
||||
DEFINES += -DMOZ_JSDEBUGGER
|
||||
endif
|
||||
|
||||
nsXPConnect.$(OBJ_SUFFIX): dom_quickstubs.h
|
||||
|
||||
XPCJSRuntime.$(OBJ_SUFFIX): dom_quickstubs.h
|
||||
|
||||
dom_quickstubs.h: dom_quickstubs.cpp
|
||||
|
||||
dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
|
||||
@ -80,6 +84,8 @@ dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
|
||||
$(ENABLE_TRACEABLE_FLAGS) \
|
||||
$(srcdir)/dom_quickstubs.qsconf
|
||||
|
||||
DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.cpp
|
||||
|
||||
DictionaryHelpers.h: DictionaryHelpers.cpp
|
||||
|
||||
DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
@ -98,6 +104,9 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
$(srcdir)/dictionary_helper_gen.conf \
|
||||
event_impl_gen.conf
|
||||
|
||||
GeneratedEvents.$(OBJ_SUFFIX): GeneratedEvents.h \
|
||||
GeneratedEvents.cpp
|
||||
|
||||
event_impl_gen.conf : $(srcdir)/event_impl_gen.conf.in
|
||||
$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $^ -o event_impl_gen.conf)
|
||||
|
||||
@ -145,6 +154,13 @@ GeneratedEvents-webidl: event_impl_gen.conf
|
||||
event_impl_gen.conf
|
||||
|
||||
GARBAGE += \
|
||||
dom_quickstubs.h \
|
||||
dom_quickstubs.cpp \
|
||||
DictionaryHelpers.h \
|
||||
DictionaryHelpers.cpp \
|
||||
GeneratedEvents.h \
|
||||
GeneratedEvents.cpp \
|
||||
GeneratedEventClasses.h \
|
||||
event_impl_gen.conf \
|
||||
xpidl_debug \
|
||||
$(MDDEPDIR)/dom_qsgen.pp \
|
||||
|
@ -13,12 +13,13 @@ EXPORTS += [
|
||||
'xpcpublic.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'nsCxPusher.cpp',
|
||||
'nsScriptError.cpp',
|
||||
'nsXPConnect.cpp',
|
||||
'Sandbox.cpp',
|
||||
'XPCCallContext.cpp',
|
||||
'XPCComponents.cpp',
|
||||
'XPCContext.cpp',
|
||||
'XPCConvert.cpp',
|
||||
'XPCDebug.cpp',
|
||||
@ -47,11 +48,6 @@ UNIFIED_SOURCES += [
|
||||
'XPCWrapper.cpp',
|
||||
]
|
||||
|
||||
# XPCComponents.cpp cannot be built in unified mode because it uses plarena.h.
|
||||
SOURCES += [
|
||||
'XPCComponents.cpp',
|
||||
]
|
||||
|
||||
GENERATED_SOURCES += [
|
||||
'DictionaryHelpers.cpp',
|
||||
'dom_quickstubs.cpp',
|
||||
@ -67,10 +63,3 @@ LIBRARY_NAME = 'xpconnect_s'
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'gklayout'
|
||||
|
||||
GENERATED_FILES = [
|
||||
'DictionaryHelpers.h',
|
||||
'dom_quickstubs.h',
|
||||
'GeneratedEventClasses.h',
|
||||
'GeneratedEvents.h',
|
||||
]
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
NO_DIST_INSTALL = True
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'xpctest_attributes.cpp',
|
||||
'xpctest_module.cpp',
|
||||
'xpctest_params.cpp',
|
||||
|
@ -671,7 +671,7 @@ nsIGlobalObject *
|
||||
GetNativeForGlobal(JSObject *obj)
|
||||
{
|
||||
MOZ_ASSERT(JS_IsGlobalObject(obj));
|
||||
if (!EnsureCompartmentPrivate(obj)->scope)
|
||||
if (!MaybeGetObjectScope(obj))
|
||||
return nullptr;
|
||||
|
||||
// Every global needs to hold a native as its private.
|
||||
|
@ -8,16 +8,12 @@ EXPORTS += [
|
||||
'WrapperFactory.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'AccessCheck.cpp',
|
||||
'ChromeObjectWrapper.cpp',
|
||||
'FilteringWrapper.cpp',
|
||||
'WaiveXrayWrapper.cpp',
|
||||
'WrapperFactory.cpp',
|
||||
]
|
||||
|
||||
# XrayWrapper needs to be built separately becaue of template instantiations.
|
||||
SOURCES += [
|
||||
'XrayWrapper.cpp',
|
||||
]
|
||||
|
||||
|
@ -1714,6 +1714,21 @@ ElementForStyleContext(nsIContent* aParentContent,
|
||||
return grandparentFrame->GetContent()->AsElement();
|
||||
}
|
||||
|
||||
if (aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberText ||
|
||||
aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberWrapper ||
|
||||
aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox ||
|
||||
aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp ||
|
||||
aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown) {
|
||||
// Get content for nearest nsNumberControlFrame:
|
||||
nsIFrame* f = aFrame->GetParent();
|
||||
MOZ_ASSERT(f);
|
||||
while (f->GetType() != nsGkAtoms::numberControlFrame) {
|
||||
f = f->GetParent();
|
||||
MOZ_ASSERT(f);
|
||||
}
|
||||
return f->GetContent()->AsElement();
|
||||
}
|
||||
|
||||
nsIContent* content = aParentContent ? aParentContent : aFrame->GetContent();
|
||||
return content->AsElement();
|
||||
}
|
||||
|
@ -3393,7 +3393,7 @@ nsCSSFrameConstructor::FindInputData(Element* aElement,
|
||||
FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewColorControlFrame,
|
||||
nsCSSAnonBoxes::buttonContent) },
|
||||
// TODO: this is temporary until a frame is written: bug 635240.
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewNumberControlFrame),
|
||||
// TODO: this is temporary until a frame is written: bug 773205.
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame),
|
||||
// TODO: this is temporary until a frame is written: bug 773205
|
||||
|
@ -29,6 +29,7 @@ UNIFIED_SOURCES += [
|
||||
'nsLegendFrame.cpp',
|
||||
'nsListControlFrame.cpp',
|
||||
'nsMeterFrame.cpp',
|
||||
'nsNumberControlFrame.cpp',
|
||||
'nsProgressFrame.cpp',
|
||||
'nsRangeFrame.cpp',
|
||||
'nsSelectsAreaFrame.cpp',
|
||||
|
343
layout/forms/nsNumberControlFrame.cpp
Normal file
343
layout/forms/nsNumberControlFrame.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNumberControlFrame.h"
|
||||
|
||||
#include "HTMLInputElement.h"
|
||||
#include "nsIFocusManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsFormControlFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentList.h"
|
||||
#include "nsStyleSet.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsIFrame*
|
||||
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
return new (aPresShell) nsNumberControlFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsNumberControlFrame)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsNumberControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsNumberControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
nsNumberControlFrame::nsNumberControlFrame(nsStyleContext* aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
, mHandlingInputEvent(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsNumberControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
|
||||
"nsNumberControlFrame 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(&mOuterWrapper);
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsNumberControlFrame");
|
||||
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
|
||||
|
||||
NS_ASSERTION(mOuterWrapper, "Outer wrapper div must exist!");
|
||||
|
||||
NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
|
||||
"nsNumberControlFrame should not have continuations; if it does we "
|
||||
"need to call RegUnregAccessKey only for the first");
|
||||
|
||||
NS_ASSERTION(!mFrames.FirstChild() ||
|
||||
!mFrames.FirstChild()->GetNextSibling(),
|
||||
"We expect at most one direct child frame");
|
||||
|
||||
if (mState & NS_FRAME_FIRST_REFLOW) {
|
||||
nsFormControlFrame::RegUnRegAccessKey(this, true);
|
||||
}
|
||||
|
||||
nsHTMLReflowMetrics wrappersDesiredSize;
|
||||
nsIFrame* outerWrapperFrame = mOuterWrapper->GetPrimaryFrame();
|
||||
if (outerWrapperFrame) { // display:none?
|
||||
NS_ASSERTION(outerWrapperFrame == mFrames.FirstChild(), "huh?");
|
||||
nsresult rv =
|
||||
ReflowAnonymousContent(aPresContext, wrappersDesiredSize,
|
||||
aReflowState, outerWrapperFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, outerWrapperFrame);
|
||||
}
|
||||
|
||||
nscoord computedHeight = aReflowState.ComputedHeight();
|
||||
if (computedHeight == NS_AUTOHEIGHT) {
|
||||
computedHeight =
|
||||
outerWrapperFrame ? outerWrapperFrame->GetSize().height : 0;
|
||||
}
|
||||
aDesiredSize.width = aReflowState.ComputedWidth() +
|
||||
aReflowState.mComputedBorderPadding.LeftRight();
|
||||
aDesiredSize.height = computedHeight +
|
||||
aReflowState.mComputedBorderPadding.TopBottom();
|
||||
|
||||
if (outerWrapperFrame) {
|
||||
aDesiredSize.ascent = wrappersDesiredSize.ascent +
|
||||
outerWrapperFrame->GetPosition().y;
|
||||
}
|
||||
|
||||
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
||||
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::
|
||||
ReflowAnonymousContent(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aWrappersDesiredSize,
|
||||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aOuterWrapperFrame)
|
||||
{
|
||||
MOZ_ASSERT(aOuterWrapperFrame);
|
||||
|
||||
// The width of our content box, which is the available width
|
||||
// for our anonymous content:
|
||||
nscoord inputFrameContentBoxWidth = aParentReflowState.ComputedWidth();
|
||||
|
||||
nsHTMLReflowState wrapperReflowState(aPresContext, aParentReflowState,
|
||||
aOuterWrapperFrame,
|
||||
nsSize(inputFrameContentBoxWidth,
|
||||
NS_UNCONSTRAINEDSIZE));
|
||||
|
||||
nscoord xoffset = aParentReflowState.mComputedBorderPadding.left +
|
||||
wrapperReflowState.mComputedMargin.left;
|
||||
nscoord yoffset = aParentReflowState.mComputedBorderPadding.top +
|
||||
wrapperReflowState.mComputedMargin.top;
|
||||
|
||||
nsReflowStatus childStatus;
|
||||
nsresult rv = ReflowChild(aOuterWrapperFrame, aPresContext,
|
||||
aWrappersDesiredSize, wrapperReflowState,
|
||||
xoffset, yoffset, 0, childStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(childStatus),
|
||||
"We gave our child unconstrained height, so it should be complete");
|
||||
return FinishReflowChild(aOuterWrapperFrame, aPresContext,
|
||||
&wrapperReflowState, aWrappersDesiredSize,
|
||||
xoffset, yoffset, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::placeholder ||
|
||||
aAttribute == nsGkAtoms::readonly) {
|
||||
if (aModType == nsIDOMMutationEvent::REMOVAL) {
|
||||
mTextField->UnsetAttr(aNameSpaceID, aAttribute, true);
|
||||
} else {
|
||||
MOZ_ASSERT(aModType == nsIDOMMutationEvent::ADDITION ||
|
||||
aModType == nsIDOMMutationEvent::MODIFICATION);
|
||||
nsAutoString value;
|
||||
mContent->GetAttr(aNameSpaceID, aAttribute, value);
|
||||
mTextField->SetAttr(aNameSpaceID, aAttribute, value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
|
||||
aModType);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::MakeAnonymousElement(nsIContent** aResult,
|
||||
nsTArray<ContentInfo>& aElements,
|
||||
nsIAtom* aTagName,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
nsStyleContext* aParentContext)
|
||||
{
|
||||
// Get the NodeInfoManager and tag necessary to create the anonymous divs.
|
||||
nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTagName, nullptr,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsresult rv = NS_NewHTMLElement(aResult, nodeInfo.forget(),
|
||||
dom::NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we legitimately fail this assertion and need to allow
|
||||
// non-pseudo-element anonymous children, then we'll need to add a branch
|
||||
// that calls ResolveStyleFor((*aResult)->AsElement(), aParentContext)") to
|
||||
// set newStyleContext.
|
||||
NS_ASSERTION(aPseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||
"Expecting anonymous children to all be pseudo-elements");
|
||||
// Associate the pseudo-element with the anonymous child
|
||||
nsRefPtr<nsStyleContext> newStyleContext =
|
||||
PresContext()->StyleSet()->ResolvePseudoElementStyle(mContent->AsElement(),
|
||||
aPseudoType,
|
||||
aParentContext);
|
||||
|
||||
if (!aElements.AppendElement(ContentInfo(*aResult, newStyleContext))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// We create an anonymous tree for our input element that is structured as
|
||||
// follows:
|
||||
//
|
||||
// input
|
||||
// div - outer wrapper with "display:flex" by default
|
||||
// input - text input field
|
||||
// div - spin box wrapping up/down arrow buttons
|
||||
// div - spin up (up arrow button)
|
||||
// div - spin down (down arrow button)
|
||||
//
|
||||
// If you change this, be careful to change the destruction order in
|
||||
// nsNumberControlFrame::DestroyFrom.
|
||||
|
||||
|
||||
// Create the anonymous outer wrapper:
|
||||
rv = MakeAnonymousElement(getter_AddRefs(mOuterWrapper),
|
||||
aElements,
|
||||
nsGkAtoms::div,
|
||||
nsCSSPseudoElements::ePseudo_mozNumberWrapper,
|
||||
mStyleContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ContentInfo& outerWrapperCI = aElements.LastElement();
|
||||
|
||||
// Create the ::-moz-number-text pseudo-element:
|
||||
rv = MakeAnonymousElement(getter_AddRefs(mTextField),
|
||||
outerWrapperCI.mChildren,
|
||||
nsGkAtoms::input,
|
||||
nsCSSPseudoElements::ePseudo_mozNumberText,
|
||||
outerWrapperCI.mStyleContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
NS_LITERAL_STRING("text"), PR_FALSE);
|
||||
|
||||
// Initialize the text field value:
|
||||
nsAutoString value;
|
||||
HTMLInputElement::FromContent(mContent)->GetValue(value);
|
||||
mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::value, value, false);
|
||||
|
||||
// If we're readonly, make sure our anonymous text control is too:
|
||||
nsAutoString readonly;
|
||||
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::readonly, readonly)) {
|
||||
mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::readonly, readonly, false);
|
||||
}
|
||||
|
||||
// Initialize the text field's placeholder, if ours is set:
|
||||
nsAutoString placeholder;
|
||||
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholder)) {
|
||||
mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholder, false);
|
||||
}
|
||||
|
||||
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS)) {
|
||||
// We don't want to focus the frame but the text field.
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mTextField);
|
||||
NS_ASSERTION(element, "Really, this should be a nsIDOMElement!");
|
||||
fm->SetFocus(element, 0);
|
||||
}
|
||||
|
||||
// Create the ::-moz-number-spin-box pseudo-element:
|
||||
rv = MakeAnonymousElement(getter_AddRefs(mSpinBox),
|
||||
outerWrapperCI.mChildren,
|
||||
nsGkAtoms::div,
|
||||
nsCSSPseudoElements::ePseudo_mozNumberSpinBox,
|
||||
outerWrapperCI.mStyleContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ContentInfo& spinBoxCI = outerWrapperCI.mChildren.LastElement();
|
||||
|
||||
// Create the ::-moz-number-spin-up pseudo-element:
|
||||
rv = MakeAnonymousElement(getter_AddRefs(mSpinUp),
|
||||
spinBoxCI.mChildren,
|
||||
nsGkAtoms::div,
|
||||
nsCSSPseudoElements::ePseudo_mozNumberSpinUp,
|
||||
spinBoxCI.mStyleContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create the ::-moz-number-spin-down pseudo-element:
|
||||
rv = MakeAnonymousElement(getter_AddRefs(mSpinDown),
|
||||
spinBoxCI.mChildren,
|
||||
nsGkAtoms::div,
|
||||
nsCSSPseudoElements::ePseudo_mozNumberSpinDown,
|
||||
spinBoxCI.mStyleContext);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsNumberControlFrame::GetType() const
|
||||
{
|
||||
return nsGkAtoms::numberControlFrame;
|
||||
}
|
||||
|
||||
HTMLInputElement*
|
||||
nsNumberControlFrame::GetAnonTextControl()
|
||||
{
|
||||
return mTextField ? HTMLInputElement::FromContent(mTextField) : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
|
||||
uint32_t aFilter)
|
||||
{
|
||||
// Only one direct anonymous child:
|
||||
aElements.MaybeAppendElement(mOuterWrapper);
|
||||
}
|
||||
|
||||
void
|
||||
nsNumberControlFrame::UpdateForValueChange(const nsAString& aValue)
|
||||
{
|
||||
if (mHandlingInputEvent) {
|
||||
// We have been called while our HTMLInputElement is processing a DOM
|
||||
// 'input' event targeted at our anonymous text control. Our
|
||||
// HTMLInputElement has taken the value of our anon text control and
|
||||
// called SetValueInternal on itself to keep its own value in sync. As a
|
||||
// result SetValueInternal has called us. In this one case we do not want
|
||||
// to update our anon text control, especially since aValue will be the
|
||||
// sanitized value, and only the internal value should be sanitized (not
|
||||
// the value shown to the user, and certainly we shouldn't change it as
|
||||
// they type).
|
||||
return;
|
||||
}
|
||||
// We need to update the value of our anonymous text control here. Note that
|
||||
// this must be its value, and not its 'value' attribute (the default value),
|
||||
// since the default value is ignored once a user types into the text
|
||||
// control.
|
||||
HTMLInputElement::FromContent(mTextField)->SetValue(aValue);
|
||||
}
|
114
layout/forms/nsNumberControlFrame.h
Normal file
114
layout/forms/nsNumberControlFrame.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNumberControlFrame_h__
|
||||
#define nsNumberControlFrame_h__
|
||||
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsPresContext;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class HTMLInputElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This frame type is used for <input type=number>.
|
||||
*/
|
||||
class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame
|
||||
, public nsIAnonymousContentCreator
|
||||
{
|
||||
friend nsIFrame*
|
||||
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
typedef mozilla::dom::HTMLInputElement HTMLInputElement;
|
||||
|
||||
nsNumberControlFrame(nsStyleContext* aContext);
|
||||
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame)
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
|
||||
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType) MOZ_OVERRIDE;
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
|
||||
virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
|
||||
uint32_t aFilter) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
|
||||
return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
|
||||
{
|
||||
return nsContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
||||
}
|
||||
|
||||
/**
|
||||
* When our HTMLInputElement's value changes, it calls this method to tell
|
||||
* us to sync up our anonymous text input field child.
|
||||
*/
|
||||
void UpdateForValueChange(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* Called to notify this frame that its HTMLInputElement is currently
|
||||
* processing a DOM 'input' event.
|
||||
*/
|
||||
void HandlingInputEvent(bool aHandlingEvent)
|
||||
{
|
||||
mHandlingInputEvent = aHandlingEvent;
|
||||
}
|
||||
|
||||
HTMLInputElement* GetAnonTextControl();
|
||||
|
||||
private:
|
||||
|
||||
nsresult MakeAnonymousElement(nsIContent** aResult,
|
||||
nsTArray<ContentInfo>& aElements,
|
||||
nsIAtom* aTagName,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
nsStyleContext* aParentContext);
|
||||
|
||||
nsresult ReflowAnonymousContent(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aWrappersDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsIFrame* aOuterWrapperFrame);
|
||||
|
||||
/**
|
||||
* The text field used to edit and show the number.
|
||||
* @see nsNumberControlFrame::CreateAnonymousContent.
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mOuterWrapper;
|
||||
nsCOMPtr<nsIContent> mTextField;
|
||||
nsCOMPtr<nsIContent> mSpinBox;
|
||||
nsCOMPtr<nsIContent> mSpinUp;
|
||||
nsCOMPtr<nsIContent> mSpinDown;
|
||||
bool mHandlingInputEvent;
|
||||
};
|
||||
|
||||
#endif // nsNumberControlFrame_h__
|
@ -102,6 +102,7 @@ FRAME_ID(nsMenuBarFrame)
|
||||
FRAME_ID(nsMenuFrame)
|
||||
FRAME_ID(nsMenuPopupFrame)
|
||||
FRAME_ID(nsMeterFrame)
|
||||
FRAME_ID(nsNumberControlFrame)
|
||||
FRAME_ID(nsObjectFrame)
|
||||
FRAME_ID(nsPageBreakFrame)
|
||||
FRAME_ID(nsPageContentFrame)
|
||||
|
@ -193,6 +193,8 @@ nsIFrame*
|
||||
NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewRangeFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
// Table frame factories
|
||||
nsIFrame*
|
||||
|
@ -1759,7 +1759,7 @@ skip-if(B2G) == 818276-1.html 818276-1-ref.html
|
||||
== 846144-1.html 846144-1-ref.html
|
||||
== 847850-1.html 847850-1-ref.html
|
||||
== 848421-1.html 848421-1-ref.html
|
||||
== 849407-1.html 849407-1-ref.html
|
||||
random-if(B2G) == 849407-1.html 849407-1-ref.html
|
||||
== 849996-1.html 849996-1-ref.html
|
||||
== 858803-1.html 858803-1-ref.html
|
||||
== 860242-1.html 860242-1-ref.html
|
||||
|
@ -4,5 +4,5 @@
|
||||
== fieldset-percentage-padding-1.html fieldset-percentage-padding-1-ref.html
|
||||
== fieldset-scroll-1.html fieldset-scroll-1-ref.html
|
||||
== fieldset-scrolled-1.html fieldset-scrolled-1-ref.html
|
||||
== fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
|
||||
random-if(B2G) == fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
|
||||
== positioned-container-1.html positioned-container-1-ref.html
|
||||
|
26
layout/reftests/forms/input/number/focus-handling-ref.html
Normal file
26
layout/reftests/forms/input/number/focus-handling-ref.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- In this case we're using reftest-wait to make sure the test doesn't
|
||||
get snapshotted before it's been focused. We're not testing
|
||||
invalidation so we don't need to listen for MozReftestInvalidate.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
|
||||
function end() {
|
||||
setTimeout(function() {
|
||||
document.documentElement.className = "";
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input style="-moz-appearance:none;"><br>
|
||||
<input autofocus onfocus="end();"
|
||||
style="-moz-appearance:none;">
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
32
layout/reftests/forms/input/number/focus-handling.html
Normal file
32
layout/reftests/forms/input/number/focus-handling.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- In this case we're using reftest-wait to make sure the test doesn't
|
||||
get snapshotted before it's been focused. We're not testing
|
||||
invalidation so we don't need to listen for MozReftestInvalidate.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
|
||||
function begin() {
|
||||
document.getElementsByTagName('input')[1].focus();
|
||||
}
|
||||
|
||||
function end() {
|
||||
setTimeout(function() {
|
||||
document.documentElement.className = "";
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input type='number' autofocus onfocus="begin();"
|
||||
style="-moz-appearance:none;"><br>
|
||||
<input type='number' onfocus="end();"
|
||||
style="-moz-appearance:none;">
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="checkbox" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when switching to another type, the input element should look
|
||||
like that type (not like an input number element) -->
|
||||
<script type="text/javascript">
|
||||
function setToCheckbox()
|
||||
{
|
||||
document.getElementById('i').type='checkbox';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", setToCheckbox);
|
||||
</script>
|
||||
<body>
|
||||
<input type='number' id='i' style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="number" value="1" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="text" value="1" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="checkbox" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="number" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
|
||||
/* None of these selectors should match from content */
|
||||
input[type=number]::-moz-number-wrapper,
|
||||
input[type=number]::-moz-number-text,
|
||||
input[type=number]::-moz-number-spin-box,
|
||||
input[type=number]::-moz-number-spin-up,
|
||||
input[type=number]::-moz-number-spin-down {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input type="number" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="text" style="-moz-appearance:none; width:200px;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="number" style="-moz-appearance:none; width:200px;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="text" style="-moz-appearance:none; width:200px;">
|
||||
<!-- div to cover spin box area -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="number" style="-moz-appearance:none; width:200px;">
|
||||
<!-- div to cover spin box area -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
25
layout/reftests/forms/input/number/reftest.list
Normal file
25
layout/reftests/forms/input/number/reftest.list
Normal file
@ -0,0 +1,25 @@
|
||||
default-preferences pref(dom.forms.number,true)
|
||||
|
||||
# sanity checks:
|
||||
# not valid on Android/B2G where type=number looks like type=text
|
||||
skip-if(Android||B2G) != not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html
|
||||
skip-if(Android||B2G) != not-other-type-unthemed-1.html not-other-type-unthemed-1b-notref.html
|
||||
# only valid on Android/B2G where type=number looks the same as type=text
|
||||
skip-if(!Android&&!B2G) == number-same-as-text-unthemed.html number-same-as-text-unthemed-ref.html
|
||||
|
||||
# should look the same as type=text, except for the spin box
|
||||
== number-similar-to-text-unthemed.html number-similar-to-text-unthemed-ref.html
|
||||
|
||||
# dynamic type changes:
|
||||
fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63,4) == to-number-from-other-type-unthemed-1.html to-number-from-other-type-unthemed-1-ref.html
|
||||
== from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1-ref.html
|
||||
|
||||
# dynamic value changes:
|
||||
== show-value.html show-value-ref.html
|
||||
|
||||
# focus
|
||||
fails-if(B2G) needs-focus == focus-handling.html focus-handling-ref.html # bug 940760
|
||||
|
||||
# pseudo-elements not usable from content:
|
||||
== number-pseudo-elements.html number-pseudo-elements-ref.html
|
||||
|
26
layout/reftests/forms/input/number/show-value-ref.html
Normal file
26
layout/reftests/forms/input/number/show-value-ref.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
|
||||
input {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input value='42'><br>
|
||||
<input value='42'><br>
|
||||
<input value='42'><br>
|
||||
<input value='42'><br>
|
||||
<input value='42'><br>
|
||||
<form>
|
||||
<input value='42'>
|
||||
</form>
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:400px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
||||
|
40
layout/reftests/forms/input/number/show-value.html
Normal file
40
layout/reftests/forms/input/number/show-value.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
|
||||
input {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
|
||||
function run() {
|
||||
var numbers = document.getElementsByTagName('input');
|
||||
numbers[2].style.display = 'inline-block'; // none -> inline-block
|
||||
numbers[3].setAttribute('value', '42');
|
||||
numbers[4].value = '42';
|
||||
numbers[5].varue = '1337'; // deliberately misspelt - should not set value
|
||||
document.forms[0].reset(); // numbers[5] value should be 42 again.
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", run);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run();">
|
||||
<input type='number' value='42'><br>
|
||||
<input value='42' type='number'><br>
|
||||
<input type='number' value='42' style="display: none;"><br>
|
||||
<input type='number' value='1337'><br>
|
||||
<input type='number' value='1337'><br>
|
||||
<form>
|
||||
<input type='number' value='42'>
|
||||
</form>
|
||||
<!-- div to cover spin box area for type=number to type=text comparison -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:400px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="number" style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: input element changed to number state doesn't look like checkbox state -->
|
||||
<script type="text/javascript">
|
||||
function setToNumber()
|
||||
{
|
||||
document.getElementById('i').type='number';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", setToNumber);
|
||||
</script>
|
||||
<body>
|
||||
<input type='checkbox' id='i' style="-moz-appearance:none;">
|
||||
</body>
|
||||
</html>
|
@ -3,6 +3,7 @@ include email/reftest.list
|
||||
include tel/reftest.list
|
||||
include search/reftest.list
|
||||
include url/reftest.list
|
||||
include number/reftest.list
|
||||
include file/reftest.list
|
||||
include radio/reftest.list
|
||||
include range/reftest.list
|
||||
|
@ -23,7 +23,7 @@ fuzzy-if(Android,2,4) == right-3.html right-3-ref.html
|
||||
== margin-1.html margin-1-ref.html
|
||||
== padding-1.html padding-1-ref.html
|
||||
== padding-2.html padding-2-ref.html
|
||||
== padding-3.html padding-3-ref.html
|
||||
random-if(B2G) == padding-3.html padding-3-ref.html
|
||||
== overcontain-1.html overcontain-1-ref.html
|
||||
== initial-1.html initial-1-ref.html
|
||||
== initial-scroll-1.html initial-scroll-1-ref.html
|
||||
|
@ -92,7 +92,7 @@ needs-focus == data:text/plain, about:blank
|
||||
# Sanity check of viewport+displayport overrides
|
||||
random-if(!browserIsRemote) == test-displayport.html test-displayport-ref.html # bug 593168
|
||||
skip-if(!browserIsRemote) != test-displayport-2.html test-displayport-ref.html # bug 593168
|
||||
skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) == 647192-1.html 647192-1-ref.html
|
||||
skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) random-if(B2G) == 647192-1.html 647192-1-ref.html
|
||||
skip-if(!browserIsRemote) == 656041-1.html 656041-1-ref.html
|
||||
skip-if(!browserIsRemote||layersOMTC) == test-displayport-bg.html test-displayport-ref.html # bug 694706
|
||||
|
||||
|
@ -881,6 +881,84 @@ input[type=range]::-moz-range-thumb {
|
||||
-moz-user-select: none ! important;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
/* Has to revert some properties applied by the generic input rule. */
|
||||
-moz-binding: none;
|
||||
width: 149px; /* to match type=text */
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-wrapper {
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: flex;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
-moz-box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-text {
|
||||
-moz-appearance: none;
|
||||
/* work around autofocus bug 939248 on initial load */
|
||||
-moz-user-modify: read-write;
|
||||
/* This pseudo-element is also an 'input' element (nested inside and
|
||||
* distinct from the <input type=number> element) so we need to prevent the
|
||||
* explicit setting of 'text-align' by the general CSS rule for 'input'
|
||||
* above. We want to inherit its value from its <input type=number>
|
||||
* ancestor, not have that general CSS rule reset it.
|
||||
*/
|
||||
text-align: inherit;
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 8px;
|
||||
cursor: default;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-up {
|
||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
||||
* flex item that will prevent the setting of the "flex" property below from
|
||||
* working.
|
||||
*/
|
||||
display: block;
|
||||
flex: 1;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,4 L3,0 5,4" fill="dimgrey"/></svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center bottom;
|
||||
border: 1px solid darkgray;
|
||||
border-bottom: none;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-down {
|
||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
||||
* flex item that will prevent the setting of the "flex" property below from
|
||||
* working.
|
||||
*/
|
||||
display: block;
|
||||
flex: 1;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,1 L3,5 5,1" fill="dimgrey"/></svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center top;
|
||||
border: 1px solid darkgray;
|
||||
border-top: none;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
input[type="number"] > div > div > div:hover {
|
||||
/* give some indication of hover state for the up/down buttons */
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
%ifdef XP_OS2
|
||||
input {
|
||||
font: medium serif; font-family: inherit
|
||||
|
@ -3661,6 +3661,18 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
|
||||
nsCSSPseudoClasses::Type pseudoClassType =
|
||||
nsCSSPseudoClasses::GetPseudoType(pseudo);
|
||||
|
||||
if (!mUnsafeRulesEnabled &&
|
||||
(pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberWrapper ||
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberText ||
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox ||
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp ||
|
||||
pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown)) {
|
||||
// Hide these pseudo-elements from content until we standardize them.
|
||||
REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
|
||||
UngetToken();
|
||||
return eSelectorParsingStatus_Error;
|
||||
}
|
||||
|
||||
// We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
|
||||
// be a bit stricter regarding the pseudo-element parsing rules.
|
||||
if (pseudoElementType == nsCSSPseudoElements::ePseudo_mozPlaceholder &&
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user