Merge central to inbound

This commit is contained in:
Justin Wood
2013-03-02 13:33:21 -05:00
191 changed files with 2724 additions and 1289 deletions

View File

@@ -28,15 +28,19 @@ SHARED_LIBRARY_LIBS = \
../src/generic/$(LIB_PREFIX)accessibility_generic_s.$(LIB_SUFFIX) \
../src/html/$(LIB_PREFIX)accessibility_html_s.$(LIB_SUFFIX) \
../src/xpcom/$(LIB_PREFIX)accessibility_xpcom_s.$(LIB_SUFFIX) \
../src/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
SHARED_LIBRARY_LIBS += \
../src/windows/msaa/$(LIB_PREFIX)accessibility_toolkit_msaa_s.$(LIB_SUFFIX) \
../src/windows/ia2/$(LIB_PREFIX)accessibility_toolkit_ia2_s.$(LIB_SUFFIX) \
../src/windows/sdn/$(LIB_PREFIX)accessibility_toolkit_sdn_s.$(LIB_SUFFIX) \
../src/windows/uia/$(LIB_PREFIX)accessibility_toolkit_uia_s.$(LIB_SUFFIX) \
$(NULL)
else
SHARED_LIBRARY_LIBS += \
../src/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) \
$(NULL)
endif
ifdef MOZ_XUL

View File

@@ -94,7 +94,7 @@ LOCAL_INCLUDES += \
else
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
LOCAL_INCLUDES += \
-I$(srcdir)/../msaa \
-I$(srcdir)/../windows/msaa \
-I$(srcdir)/../windows/ia2 \
$(NULL)
else

View File

@@ -60,7 +60,7 @@ LOCAL_INCLUDES += \
else
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
LOCAL_INCLUDES += \
-I$(srcdir)/../msaa \
-I$(srcdir)/../windows/msaa \
$(NULL)
else
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)

View File

@@ -50,7 +50,7 @@ LOCAL_INCLUDES += \
else
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
LOCAL_INCLUDES += \
-I$(srcdir)/../msaa \
-I$(srcdir)/../windows/msaa \
-I$(srcdir)/../windows/ia2 \
$(NULL)
else

View File

@@ -8,7 +8,7 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
if toolkit == 'gtk2':
DIRS += ['atk']
elif toolkit == 'windows':
DIRS += ['msaa', 'windows']
DIRS += ['windows']
elif toolkit == 'cocoa':
DIRS += ['mac']
else:

View File

@@ -51,10 +51,10 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../msaa \
-I$(srcdir)/../../base \
-I$(srcdir)/../../generic \
-I$(srcdir)/../../html \
-I$(srcdir)/../../msaa \
-I$(srcdir)/../../xpcom \
-I$(srcdir)/../../xul \
$(NULL)

View File

@@ -3,5 +3,5 @@
# 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/.
DIRS += ['ia2', 'sdn', 'uia']
DIRS += ['msaa', 'ia2', 'sdn', 'uia']

View File

@@ -10,8 +10,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = accessibility
LIBRARY_NAME = accessibility_toolkit_s
EXPORT_LIBRARY = ..
LIBRARY_NAME = accessibility_toolkit_msaa_s
EXPORT_LIBRARY = 1
LIBXUL_LIBRARY = 1
@@ -63,16 +63,16 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(srcdir)/../windows/ia2 \
-I$(srcdir)/../windows/sdn \
-I$(srcdir)/../windows/uia \
-I$(srcdir)/../../../content/base/src \
-I$(srcdir)/../../../content/events/src \
-I$(srcdir)/../../base \
-I$(srcdir)/../../generic \
-I$(srcdir)/../../html \
-I$(srcdir)/../../xpcom \
-I$(srcdir)/../../xul \
-I$(srcdir)/../ia2 \
-I$(srcdir)/../sdn \
-I$(srcdir)/../uia \
-I$(srcdir)/../../../../content/base/src \
-I$(srcdir)/../../../../content/events/src \
$(NULL)
ifneq ($(A11Y_LOG),0)

View File

@@ -29,10 +29,10 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../msaa \
-I$(srcdir)/../../base \
-I$(srcdir)/../../generic \
-I$(srcdir)/../../html \
-I$(srcdir)/../../msaa \
-I$(srcdir)/../../xpcom \
-I$(srcdir)/../../xul \
$(NULL)

View File

@@ -30,10 +30,10 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../msaa \
-I$(srcdir)/../../base \
-I$(srcdir)/../../generic \
-I$(srcdir)/../../html \
-I$(srcdir)/../../msaa \
-I$(srcdir)/../../xpcom \
-I$(srcdir)/../../xul \
$(NULL)

View File

@@ -38,7 +38,7 @@ LOCAL_INCLUDES += \
else
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
LOCAL_INCLUDES += \
-I$(srcdir)/../msaa \
-I$(srcdir)/../windows/msaa \
$(NULL)
else
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)

View File

@@ -53,7 +53,7 @@ LOCAL_INCLUDES += \
else
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
LOCAL_INCLUDES += \
-I$(srcdir)/../msaa \
-I$(srcdir)/../windows/msaa \
-I$(srcdir)/../windows/ia2 \
$(NULL)
else

View File

@@ -351,8 +351,14 @@ let SocialChatBar = {
return !!this.chatbar.firstElementChild;
},
openChat: function(aProvider, aURL, aCallback, aMode) {
if (this.isAvailable)
if (this.isAvailable) {
this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
// We only want to focus the chat if it is as a result of user input.
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
if (dwu.isHandlingUserInput)
this.chatbar.focus();
}
},
update: function() {
let command = document.getElementById("Social:FocusChat");

View File

@@ -20,6 +20,37 @@
</content>
<implementation implements="nsIDOMEventListener">
<constructor><![CDATA[
let Social = Components.utils.import("resource:///modules/Social.jsm", {}).Social;
Social.setErrorListener(this.iframe, function(iframe) {
iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null);
});
let iframeWindow = this.iframe.contentWindow;
this.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
this.removeEventListener("DOMContentLoaded", DOMContentLoaded);
this.isActive = !this.minimized;
// process this._callbacks, then set to null so the chatbox creator
// knows to make new callbacks immediately.
for (let callback of this._callbacks) {
if (callback)
callback(iframeWindow);
}
this._callbacks = null;
// content can send a socialChatActivity event to have the UI update.
let chatActivity = function() {
this.setAttribute("activity", true);
this.parentNode.updateTitlebar(this);
}.bind(this);
iframeWindow.addEventListener("socialChatActivity", chatActivity);
iframeWindow.addEventListener("unload", function unload() {
iframeWindow.removeEventListener("unload", unload);
iframeWindow.removeEventListener("socialChatActivity", chatActivity);
});
});
this.setAttribute("src", this.src);
]]></constructor>
<field name="iframe" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "iframe");
</field>
@@ -61,9 +92,12 @@
<method name="onTitlebarClick">
<parameter name="aEvent"/>
<body><![CDATA[
if (aEvent.button == 0) // left-click: toggle minimized.
if (aEvent.button == 0) { // left-click: toggle minimized.
this.toggle();
else if (aEvent.button == 1) // middle-click: close chat
// if we restored it, we want to focus it.
if (!this.minimized)
this.parentNode.focus();
} else if (aEvent.button == 1) // middle-click: close chat
this.close();
]]></body>
</method>
@@ -145,8 +179,25 @@
<body><![CDATA[
if (!this.selectedChat)
return;
let commandDispatcher = gBrowser.ownerDocument.commandDispatcher;
commandDispatcher.advanceFocusIntoSubtree(this.selectedChat);
Services.focus.focusedWindow = this.selectedChat.iframe.contentWindow;
]]></body>
</method>
<method name="_isChatFocused">
<parameter name="aChatbox"/>
<body><![CDATA[
// If there are no XBL bindings for the chat it can't be focused.
if (!aChatbox.iframe)
return false;
let fw = Services.focus.focusedWindow;
if (!fw)
return false;
// We want to see if the focused window is in the subtree below our iframe...
let containingBrowser = fw.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
return containingBrowser == aChatbox.iframe;
]]></body>
</method>
@@ -168,7 +219,6 @@
this._selectedChat = val;
if (val) {
this._selectedChat.setAttribute("selected", "true");
this.focus();
}
}
if (val) {
@@ -231,9 +281,12 @@
// It's possible in the future we will track most-recently-selected
// chats or similar to find the "best" candidate - for now though
// the choice is somewhat arbitrary.
let moveFocus = this.selectedChat && this._isChatFocused(this.selectedChat);
for (let other of this.children) {
if (other != this.selectedChat && !other.minimized && !other.collapsed) {
this.selectedChat = other;
if (moveFocus)
this.focus();
return;
}
}
@@ -381,51 +434,6 @@
]]></body>
</method>
<method name="initChatBox">
<!-- ideally this would be a method on the chatbox itself, but the
vagaries of XBL bindings means that in some edge cases the
chatbox methods don't exist yet when we need them to...
-->
<parameter name="aChatBox"/>
<parameter name="aProvider"/>
<parameter name="aURL"/>
<parameter name="aCallback"/>
<body><![CDATA[
// callbacks to be called when onload fires - more might be added
// if the same chat is requested before onload has fired. Set back
// to null in DOMContentLoaded, so null means DOMContentLoaded has
// already fired and new callbacks can be made immediately.
aChatBox._callbacks = [aCallback];
var tmp = {};
Components.utils.import("resource:///modules/Social.jsm", tmp);
tmp.Social.setErrorListener(aChatBox.iframe, function(iframe) {
iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null);
});
let iframeWindow = aChatBox.iframe.contentWindow;
aChatBox.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
aChatBox.removeEventListener("DOMContentLoaded", DOMContentLoaded);
aChatBox.isActive = !aChatBox.minimized;
for (let callback of aChatBox._callbacks) {
if (callback)
callback(iframeWindow);
}
aChatBox._callbacks = null;
function chatActivity() {
aChatBox.setAttribute("activity", true);
aChatBox.parentNode.updateTitlebar(aChatBox);
};
iframeWindow.addEventListener("socialChatActivity", chatActivity);
iframeWindow.addEventListener("unload", function unload() {
iframeWindow.removeEventListener("unload", unload);
iframeWindow.removeEventListener("socialChatActivity", chatActivity);
});
});
aChatBox.setAttribute("origin", aProvider.origin);
aChatBox.setAttribute("src", aURL);
]]></body>
</method>
<method name="openChat">
<parameter name="aProvider"/>
<parameter name="aURL"/>
@@ -451,11 +459,16 @@
this.chatboxForURL.delete(aURL);
}
cb = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "chatbox");
// _callbacks is a javascript property instead of a <field> as it
// must exist before the (possibly delayed) bindings are created.
cb._callbacks = [aCallback];
// src also a javascript property; the src attribute is set in the ctor.
cb.src = aURL;
if (aMode == "minimized")
cb.setAttribute("minimized", "true");
cb.setAttribute("origin", aProvider.origin);
this.insertBefore(cb, this.firstChild);
this.selectedChat = cb;
this.initChatBox(cb, aProvider, aURL, aCallback);
this.chatboxForURL.set(aURL, Cu.getWeakReference(cb));
this.resize();
]]></body>

View File

@@ -24,6 +24,7 @@ _BROWSER_FILES = \
browser_social_mozSocial_API.js \
browser_social_isVisible.js \
browser_social_chatwindow.js \
browser_social_chatwindowfocus.js \
browser_social_multiprovider.js \
browser_social_errorPage.js \
social_panel.html \

View File

@@ -0,0 +1,309 @@
/* 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/. */
// Is the currently opened tab focused?
function isTabFocused() {
let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab);
return Services.focus.focusedWindow == tabb.contentWindow;
}
function isChatFocused(chat) {
return SocialChatBar.chatbar._isChatFocused(chat);
}
function openChatViaUser() {
let sidebarDoc = document.getElementById("social-sidebar-browser").contentDocument;
let button = sidebarDoc.getElementById("chat-opener");
// Note we must use synthesizeMouseAtCenter() rather than calling
// .click() directly as this causes nsIDOMWindowUtils.isHandlingUserInput
// to be true.
EventUtils.synthesizeMouseAtCenter(button, {}, sidebarDoc.defaultView);
}
function openChatViaSidebarMessage(port, data, callback) {
port.onmessage = function (e) {
if (e.data.topic == "chatbox-opened")
callback();
}
port.postMessage({topic: "test-chatbox-open", data: data});
}
function openChatViaWorkerMessage(port, data, callback) {
// sadly there is no message coming back to tell us when the chat has
// been opened, so we wait until one appears.
let chatbar = SocialChatBar.chatbar;
let numExpected = chatbar.childElementCount + 1;
port.postMessage({topic: "test-worker-chat", data: data});
waitForCondition(function() chatbar.childElementCount == numExpected,
function() {
// so the child has been added, but we don't know if it
// has been intialized - re-request it and the callback
// means it's done. Minimized, same as the worker.
SocialChatBar.openChat(Social.provider,
data,
function() {
callback();
},
"minimized");
},
"No new chat appeared");
}
let isSidebarLoaded = false;
function startTestAndWaitForSidebar(callback) {
let doneCallback;
let port = Social.provider.getWorkerPort();
function maybeCallback() {
if (!doneCallback)
callback(port);
doneCallback = true;
}
port.onmessage = function(e) {
let topic = e.data.topic;
switch (topic) {
case "got-sidebar-message":
isSidebarLoaded = true;
maybeCallback();
break;
case "test-init-done":
if (isSidebarLoaded)
maybeCallback();
break;
}
}
port.postMessage({topic: "test-init"});
}
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
function test() {
waitForExplicitFinish();
// Note that (probably) due to bug 604289, if a tab is focused but the
// focused element is null, our chat windows can "steal" focus. This is
// avoided if we explicitly focus an element in the tab.
// So we load a page with an <input> field and focus that before testing.
let url = "data:text/html;charset=utf-8," + encodeURI('<input id="theinput">');
let tab = gBrowser.selectedTab = gBrowser.addTab(url, {skipAnimation: true});
tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
tab.linkedBrowser.removeEventListener("load", tabLoad, true);
// before every test we focus the input field.
let preSubTest = function(cb) {
// XXX - when bug 604289 is fixed it should be possible to just do:
// tab.linkedBrowser.contentWindow.focus()
// but instead we must do:
tab.linkedBrowser.contentDocument.getElementById("theinput").focus();
cb();
}
let postSubTest = function(cb) {
window.SocialChatBar.chatbar.removeAll();
cb();
}
// and run the tests.
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, preSubTest, postSubTest, function () {
finishcb();
});
});
}, true);
registerCleanupFunction(function() {
gBrowser.removeTab(tab);
});
}
var tests = {
// In this test the worker asks the sidebar to open a chat. As that means
// we aren't handling user-input we will not focus the chatbar.
// Then we do it again - should still not be focused.
// Then we perform a user-initiated request - it should get focus.
testNoFocusWhenViaWorker: function(next) {
startTestAndWaitForSidebar(function(port) {
openChatViaSidebarMessage(port, {stealFocus: 1}, function() {
ok(true, "got chatbox message");
is(SocialChatBar.chatbar.childElementCount, 1, "exactly 1 chat open");
ok(isTabFocused(), "tab should still be focused");
// re-request the same chat via a message.
openChatViaSidebarMessage(port, {stealFocus: 1}, function() {
is(SocialChatBar.chatbar.childElementCount, 1, "still exactly 1 chat open");
ok(isTabFocused(), "tab should still be focused");
// re-request the same chat via user event.
openChatViaUser();
is(SocialChatBar.chatbar.childElementCount, 1, "still exactly 1 chat open");
// should now be focused
ok(isChatFocused(SocialChatBar.chatbar.firstElementChild), "chat should be focused");
next();
});
});
});
},
// In this test we arrange for the sidebar to open the chat via a simulated
// click. This should cause the new chat to be opened and focused.
testFocusWhenViaUser: function(next) {
startTestAndWaitForSidebar(function(port) {
openChatViaUser();
ok(SocialChatBar.chatbar.firstElementChild, "chat opened");
ok(isChatFocused(SocialChatBar.chatbar.firstElementChild), "chat should be focused");
next();
});
},
// Open a chat via the worker - it will open minimized and not have focus.
// Then open the same chat via a sidebar message - it will be restored but
// should still not have grabbed focus.
testNoFocusOnAutoRestore: function(next) {
const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html?id=1";
let chatbar = SocialChatBar.chatbar;
startTestAndWaitForSidebar(function(port) {
openChatViaWorkerMessage(port, chatUrl, function() {
is(chatbar.childElementCount, 1, "exactly 1 chat open");
ok(chatbar.firstElementChild.minimized, "chat is minimized");
ok(isTabFocused(), "tab should be focused");
openChatViaSidebarMessage(port, {stealFocus: 1, id: 1}, function() {
is(chatbar.childElementCount, 1, "still 1 chat open");
ok(!chatbar.firstElementChild.minimized, "chat no longer minimized");
ok(isTabFocused(), "tab should still be focused");
next();
});
});
});
},
// Here we open a chat, which will not be focused. Then we minimize it and
// restore it via a titlebar clock - it should get focus at that point.
testFocusOnExplicitRestore: function(next) {
startTestAndWaitForSidebar(function(port) {
openChatViaSidebarMessage(port, {stealFocus: 1}, function() {
ok(true, "got chatbox message");
ok(isTabFocused(), "tab should still be focused");
let chatbox = SocialChatBar.chatbar.firstElementChild;
ok(chatbox, "chat opened");
chatbox.minimized = true;
ok(isTabFocused(), "tab should still be focused");
// pretend we clicked on the titlebar
chatbox.onTitlebarClick({button: 0});
ok(!chatbox.minimized, "chat should have been restored");
ok(isChatFocused(chatbox), "chat should be focused");
next();
});
});
},
// Open 2 chats and give 1 focus. Minimize the focused one - the second
// should get focus.
testMinimizeFocused: function(next) {
let chatbar = SocialChatBar.chatbar;
startTestAndWaitForSidebar(function(port) {
openChatViaSidebarMessage(port, {stealFocus: 1, id: 1}, function() {
let chat1 = chatbar.firstElementChild;
openChatViaSidebarMessage(port, {stealFocus: 1, id: 2}, function() {
is(chatbar.childElementCount, 2, "exactly 2 chats open");
let chat2 = chat1.nextElementSibling || chat1.previousElementSibling;
chatbar.selectedChat = chat1;
chatbar.focus();
ok(isChatFocused(chat1), "first chat should be focused");
chat1.minimized = true;
// minimizing the chat with focus should give it to another.
ok(isChatFocused(chat2), "second chat should be focused");
next();
});
});
});
},
// Open 2 chats, select (but not focus) one, then re-request it be
// opened via a message. Focus should not move.
testReopenNonFocused: function(next) {
let chatbar = SocialChatBar.chatbar;
startTestAndWaitForSidebar(function(port) {
openChatViaSidebarMessage(port, {id: 1}, function() {
let chat1 = chatbar.firstElementChild;
openChatViaSidebarMessage(port, {id: 2}, function() {
let chat2 = chat1.nextElementSibling || chat1.previousElementSibling;
chatbar.selectedChat = chat2;
// tab still has focus
ok(isTabFocused(), "tab should still be focused");
// re-request the first.
openChatViaSidebarMessage(port, {id: 1}, function() {
is(chatbar.selectedChat, chat1, "chat1 now selected");
ok(isTabFocused(), "tab should still be focused");
next();
});
});
});
});
},
// Open 2 chats, select and focus the second. Pressing the TAB key should
// cause focus to move between all elements in our chat window before moving
// to the next chat window.
testTab: function(next) {
let chatbar = SocialChatBar.chatbar;
startTestAndWaitForSidebar(function(port) {
openChatViaSidebarMessage(port, {id: 1}, function() {
let chat1 = chatbar.firstElementChild;
openChatViaSidebarMessage(port, {id: 2}, function() {
let chat2 = chat1.nextElementSibling || chat1.previousElementSibling;
chatbar.selectedChat = chat2;
chatbar.focus();
ok(isChatFocused(chat2), "new chat is focused");
// Our chats have 3 focusable elements, so it takes 4 TABs to move
// to the new chat.
EventUtils.sendKey("tab");
ok(isChatFocused(chat2), "new chat still focused after first tab");
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input1",
"first input field has focus");
EventUtils.sendKey("tab");
ok(isChatFocused(chat2), "new chat still focused after tab");
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
"second input field has focus");
EventUtils.sendKey("tab");
ok(isChatFocused(chat2), "new chat still focused after tab");
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "iframe",
"iframe has focus");
// this tab now should move to the next chat.
EventUtils.sendKey("tab");
ok(isChatFocused(chat1), "first chat is focused");
next();
});
});
});
},
// Open a chat and focus an element other than the first. Move focus to some
// other item (the tab itself in this case), then focus the chatbar - the
// same element that was previously focused should still have focus.
testFocusedElement: function(next) {
let chatbar = SocialChatBar.chatbar;
startTestAndWaitForSidebar(function(port) {
openChatViaUser();
let chat = chatbar.firstElementChild;
// need to wait for the content to load before we can focus it.
chat.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
chat.removeEventListener("DOMContentLoaded", DOMContentLoaded);
chat.iframe.contentDocument.getElementById("input2").focus();
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
"correct input field has focus");
// set focus to the tab.
let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab);
Services.focus.moveFocus(tabb.contentWindow, null, Services.focus.MOVEFOCUS_ROOT, 0);
ok(isTabFocused(), "tab took focus");
chatbar.focus();
ok(isChatFocused(chat), "chat took focus");
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
"correct input field still has focus");
next();
});
});
},
};

View File

@@ -21,6 +21,10 @@
</head>
<body onload="pingWorker();">
<p>This is a test social chat window.</p>
<!-- a couple of input fields to help with focus testing -->
<input id="input1"/>
<input id="input2"/>
<!-- an iframe here so this one page generates multiple load events -->
<iframe id="iframe" src="data:text/plain:this is an iframe"></iframe>
</body>

View File

@@ -21,6 +21,11 @@
url = url + "?id="+data.id;
}
navigator.mozSocial.openChatWindow(url, function(chatwin) {
// Note that the following .focus() call should *not* arrange
// to steal focus - see browser_social_chatwindowfocus.js
if (data && data.stealFocus && chatwin) {
chatwin.focus();
}
port.postMessage({topic: "chatbox-opened",
result: chatwin ? "ok" : "failed"});
});
@@ -37,5 +42,6 @@
</head>
<body onload="pingWorker();">
<p>This is a test social sidebar.</p>
<button id="chat-opener" onclick="navigator.mozSocial.openChatWindow('./social_chat.html');"/>
</body>
</html>

View File

@@ -10,6 +10,15 @@
var ContextCommands = {
_picker: null,
get _ellipsis() {
delete this._ellipsis;
this._ellipsis = "\u2026";
try {
this._ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
} catch (ex) { }
return this._ellipsis;
},
get clipboard() {
return Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);
@@ -98,6 +107,7 @@ var ContextCommands = {
searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) {
let defaultURI;
let defaultName;
aSearchString = aSearchString.trim();
try {
let defaultPB = Services.prefs.getDefaultBranch(null);
const nsIPLS = Ci.nsIPrefLocalizedString;
@@ -108,11 +118,15 @@ var ContextCommands = {
Cu.reportError(ex);
return false;
}
let displayString = aSearchString;
if (displayString.length > 15) {
displayString = displayString.substring(0, 15) + this._ellipsis;
}
// label child node
let label = Services.strings
.createBundle("chrome://browser/locale/browser.properties")
.formatStringFromName("browser.search.contextTextSearchLabel",
[defaultName], 1);
.formatStringFromName("browser.search.contextTextSearchLabel2",
[defaultName, displayString], 2);
aRichListItem.childNodes[0].setAttribute("value", label);
aRichListItem.setAttribute("searchString", defaultURI);
return true;
@@ -355,7 +369,6 @@ var ContextCommands = {
var newDir = file.parent.QueryInterface(Ci.nsILocalFile);
Services.prefs.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, newDir);
},
};
function AutoChosen(aFileAutoChosen, aUriAutoChosen) {

View File

@@ -758,6 +758,32 @@ var BrowserUI = {
}
},
openFile: function() {
try {
const nsIFilePicker = Ci.nsIFilePicker;
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
let self = this;
let fpCallback = function fpCallback_done(aResult) {
if (aResult == nsIFilePicker.returnOK) {
self.goToURI(fp.fileURL.spec);
}
};
let windowTitle = Strings.browser.GetStringFromName("browserForOpenLocation");
fp.init(window, windowTitle, nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText |
nsIFilePicker.filterImages | nsIFilePicker.filterXML |
nsIFilePicker.filterHTML);
fp.open(fpCallback);
} catch (ex) {
dump ('BrowserUI openFile exception: ' + ex + '\n');
}
},
savePage: function() {
Browser.savePage();
},
receiveMessage: function receiveMessage(aMessage) {
let browser = aMessage.target;
let json = aMessage.json;
@@ -812,6 +838,8 @@ var BrowserUI = {
case "cmd_zoomout":
case "cmd_volumeLeft":
case "cmd_volumeRight":
case "cmd_openFile":
case "cmd_savePage":
isSupported = true;
break;
default:
@@ -935,6 +963,12 @@ var BrowserUI = {
// Zoom out (portrait) or in (landscape)
Browser.zoom(Util.isPortrait() ? 1 : -1);
break;
case "cmd_openFile":
this.openFile();
break;
case "cmd_savePage":
this.savePage();
break;
}
}
};

View File

@@ -476,6 +476,10 @@ var Browser = {
tab.browser.messageManager.sendAsyncMessage("Browser:CanUnload", {});
},
savePage: function() {
ContentAreaUtils.saveDocument(this.selectedBrowser.contentWindow.document);
},
_doCloseTab: function _doCloseTab(aTab) {
let nextTab = this._getNextTab(aTab);
if (!nextTab)

View File

@@ -67,6 +67,8 @@
<command id="cmd_go" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_openLocation" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_home" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_openFile" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_savePage" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- tabs -->
<command id="cmd_newTab" oncommand="CommandUpdater.doCommand(this.id);"/>
@@ -133,6 +135,8 @@
<key id="key_focusURL" key="l" modifiers="accel" command="cmd_openLocation"/>
<key id="key_focusURL2" key="&urlbar.accesskey;" modifiers="alt" command="cmd_openLocation"/>
<key id="key_home" keycode="VK_HOME" modifiers="accel" command="cmd_home"/>
<key id="key_open" key="o" modifiers="accel" command="cmd_openFile"/>
<key id="key_save" key="s" modifiers="accel" command="cmd_savePage"/>
<!-- misc -->
<key id="key_zoomin" key="+" modifiers="accel" command="cmd_zoomin"/>
@@ -572,6 +576,8 @@
<richlistbox id="context-commands" bindingType="contextmenu" flex="1">
<!-- priority="low" items are hidden by default when a context is being displayed
for two or more media types. (e.g. a linked image) -->
<!-- content types preceeded by '!' act as exclusion rules, the menu item will not
be displayed if the content type is present. -->
<!-- Note the order of richlistitem here is important as it is reflected in the
menu itself. -->
<!-- ux spec: https://bug782810.bugzilla.mozilla.org/attachment.cgi?id=714804 -->
@@ -585,8 +591,8 @@
<richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
<label value="&contextTextPaste.label;"/>
</richlistitem>
<!-- Search Bing for "..." -->
<richlistitem id="context-search" type="copy,selected-text" onclick="ContextCommands.searchText(this);">
<!-- Search Bing for "(text..)", displayed on selected content text only -->
<richlistitem id="context-search" type="selected-text,!input-text" onclick="ContextCommands.searchText(this);">
<label id="context-search-label" value=""/>
</richlistitem>
<!-- only display if there is text on the clipboard and the target is the urlbar -->

View File

@@ -161,6 +161,10 @@ var ContextMenuUI = {
continue;
for (let i = 0; i < types.length; i++) {
// If one of the item's types has '!' before it, treat it as an exclusion rule.
if (types[i].charAt(0) == '!' && contentTypes.indexOf(types[i].substring(1)) != -1) {
break;
}
if (contentTypes.indexOf(types[i]) != -1) {
// If this is the special search text item, we need to set its label dynamically.
if (searchTextItem && !ContextCommands.searchTextSetup(command, this._popupState.string)) {

View File

@@ -10,8 +10,8 @@ browser.search.order.1=Bing
browser.search.order.2=Google
browser.search.order.3=Yahoo
# l10n: search context menu item text will be: |Search (browser.search.defaultenginename) for ".."
browser.search.contextTextSearchLabel=Search %S for ".."
# l10n: search context menu item text will be: |Search (browser.search.defaultenginename) for "(string).."
browser.search.contextTextSearchLabel2=Search %S for "%S"
# Settings Charms
aboutCharm1=About
@@ -21,6 +21,7 @@ helpOnlineCharm=Help (online)
# General
browserForSaveLocation=Save Location
browserForOpenLocation=Open Location
# Download Manager
downloadsUnknownSize=Unknown size

60
build/mach_bootstrap.py Normal file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python
# 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/.
from __future__ import print_function, unicode_literals
import os
import platform
import sys
# TODO Bug 794506 Integrate with the in-tree virtualenv configuration.
SEARCH_PATHS = [
'python/mach',
'python/mozboot',
'python/mozbuild',
'build/pymake',
'python/blessings',
'python/psutil',
'python/which',
'other-licenses/ply',
'xpcom/idl-parser',
'testing',
'testing/xpcshell',
'testing/mozbase/mozprocess',
'testing/mozbase/mozfile',
'testing/mozbase/mozinfo',
]
# Individual files providing mach commands.
MACH_MODULES = [
'addon-sdk/mach_commands.py',
'layout/tools/reftest/mach_commands.py',
'python/mozboot/mozboot/mach_commands.py',
'python/mozbuild/mozbuild/config.py',
'python/mozbuild/mozbuild/mach_commands.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'testing/mochitest/mach_commands.py',
'testing/xpcshell/mach_commands.py',
]
def bootstrap(topsrcdir):
# Ensure we are running Python 2.7+. We put this check here so we generate a
# user-friendly error message rather than a cryptic stack trace on module
# import.
if sys.version_info[0] != 2 or sys.version_info[1] < 7:
print('Python 2.7 or above (but not Python 3) is required to run mach.')
print('You are running Python', platform.python_version())
sys.exit(1)
try:
import mach.main
except ImportError:
sys.path[0:0] = [os.path.join(topsrcdir, path) for path in SEARCH_PATHS]
import mach.main
mach = mach.main.Mach(topsrcdir)
for path in MACH_MODULES:
mach.load_commands_from_file(os.path.join(topsrcdir, path))
return mach

View File

@@ -33,6 +33,7 @@ namespace std {
template istream& istream::_M_extract(float&);
template istream& istream::_M_extract(unsigned int&);
template istream& istream::_M_extract(unsigned long&);
template istream& istream::_M_extract(unsigned short&);
#endif
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
/* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions

View File

@@ -28,6 +28,13 @@ def build_dict(env=os.environ):
if missing:
raise Exception("Missing required environment variables: %s" %
', '.join(missing))
if 'MOZCONFIG' in env:
d["mozconfig"] = env["MOZCONFIG"]
if 'TOPSRCDIR' in env:
d["topsrcdir"] = env["TOPSRCDIR"]
# os
o = env["OS_TARGET"]
known_os = {"Linux": "linux",

View File

@@ -9118,6 +9118,7 @@ MOZ_WIDGET_TOOLKIT=${MOZ_WIDGET_TOOLKIT} \
UNIVERSAL_BINARY=${UNIVERSAL_BINARY} \
MOZ_CRASHREPORTER=${MOZ_CRASHREPORTER} \
MOZ_APP_NAME=${MOZ_APP_NAME} \
TOPSRCDIR=${_topsrcdir} \
$PYTHON ${_topsrcdir}/config/writemozinfo.py ./mozinfo.json.tmp
if cmp -s ./mozinfo.json.tmp ./mozinfo.json; then
rm ./mozinfo.json.tmp

View File

@@ -14,7 +14,6 @@ interface nsIContent;
interface nsINode;
%{C++
class nsFrameSelection;
struct nsTextRangeStyle;
struct nsPoint;
struct ScrollAxis;
@@ -22,7 +21,6 @@ struct ScrollAxis;
#include "nsIFrame.h"
%}
[ptr] native nsFrameSelection(nsFrameSelection);
[ptr] native nsIFrame(nsIFrame);
[ptr] native RangeArray(nsTArray<nsRange*>);
[ref] native constTextRangeStyleRef(const nsTextRangeStyle);
@@ -30,7 +28,7 @@ struct ScrollAxis;
native nsDirection(nsDirection);
native ScrollAxis(nsIPresShell::ScrollAxis);
[scriptable, builtinclass, uuid(a6d2cedd-afbc-4d25-bffb-e725b9881e30)]
[scriptable, builtinclass, uuid(3ede44eb-2df8-41de-ab79-6f3dbd10090b)]
interface nsISelectionPrivate : nsISelection
{
const short ENDOFPRECEDINGLINE=0;
@@ -83,11 +81,6 @@ interface nsISelectionPrivate : nsISelection
*/
[noscript] void getCachedFrameOffset(in nsIFrame aFrame, in int32_t inOffset, in nsPointRef aPoint);
/* getFrameSelection
* Returnes a reference to the frame selection associated with this selection
*/
[noscript] nsFrameSelection getFrameSelection();
[noscript] void setAncestorLimiter(in nsIContent aContent);
/**

View File

@@ -2260,7 +2260,10 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
}
nsAutoCString contentType;
if (NS_SUCCEEDED(aChannel->GetContentType(contentType))) {
nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(aChannel);
if ((bag && NS_SUCCEEDED(bag->GetPropertyAsACString(
NS_LITERAL_STRING("contentType"), contentType))) ||
NS_SUCCEEDED(aChannel->GetContentType(contentType))) {
// XXX this is only necessary for viewsource:
nsACString::const_iterator start, end, semicolon;
contentType.BeginReading(start);

View File

@@ -2569,6 +2569,17 @@ SelectTextFieldOnFocus()
return gSelectTextFieldOnFocus == 1;
}
static bool
IsLTR(Element* aElement)
{
nsIFrame *frame = aElement->GetPrimaryFrame();
if (frame) {
return frame->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR;
}
// at least for HTML, directionality is exclusively LTR or RTL
return aElement->GetDirectionality() == eDir_LTR;
}
nsresult
nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
{
@@ -2835,6 +2846,74 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
NS_ENSURE_SUCCESS(rv, rv);
}
if (aVisitor.mEvent->message == NS_KEY_PRESS &&
mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() &&
!keyEvent->IsControl() && !keyEvent->IsMeta() &&
(keyEvent->keyCode == NS_VK_LEFT ||
keyEvent->keyCode == NS_VK_RIGHT ||
keyEvent->keyCode == NS_VK_UP ||
keyEvent->keyCode == NS_VK_DOWN ||
keyEvent->keyCode == NS_VK_PAGE_UP ||
keyEvent->keyCode == NS_VK_PAGE_DOWN ||
keyEvent->keyCode == NS_VK_HOME ||
keyEvent->keyCode == NS_VK_END)) {
double minimum = GetMinimum();
double maximum = GetMaximum();
MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(minimum) &&
MOZ_DOUBLE_IS_FINITE(maximum));
if (minimum < maximum) { // else the value is locked to the minimum
double value = GetValueAsDouble();
double step = GetStep();
if (step == kStepAny) {
step = GetDefaultStep();
}
MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(value) &&
MOZ_DOUBLE_IS_FINITE(step));
double newValue;
switch (keyEvent->keyCode) {
case NS_VK_LEFT:
newValue = value + (IsLTR(this) ? -step : step);
break;
case NS_VK_RIGHT:
newValue = value + (IsLTR(this) ? step : -step);
break;
case NS_VK_UP:
// Even for horizontal range, "up" means "increase"
newValue = value + step;
break;
case NS_VK_DOWN:
// Even for horizontal range, "down" means "decrease"
newValue = value - step;
break;
case NS_VK_HOME:
newValue = minimum;
break;
case NS_VK_END:
newValue = maximum;
break;
case NS_VK_PAGE_UP:
// For PgUp/PgDn we jump 10% of the total range, unless step
// requires us to jump more.
newValue = value + std::max(step, 0.1 * (maximum - minimum));
break;
case NS_VK_PAGE_DOWN:
newValue = value - std::max(step, 0.1 * (maximum - minimum));
break;
}
MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(newValue));
nsAutoString val;
ConvertNumberToString(newValue, val);
SetValueInternal(val, true, true);
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
// Trigger reflow to update the position of the thumb:
frame->PresContext()->GetPresShell()->
FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
}
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
} break; // NS_KEY_PRESS || NS_KEY_UP
case NS_MOUSE_BUTTON_DOWN:
@@ -4353,7 +4432,8 @@ nsHTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t
return true;
}
if (IsSingleLineTextControl(false)) {
if (IsSingleLineTextControl(false) ||
mType == NS_FORM_INPUT_RANGE) {
*aIsFocusable = true;
return false;
}

View File

@@ -18,6 +18,7 @@ MOCHITEST_FILES = \
test_input_attributes_reflection.html \
test_input_list_attribute.html \
test_input_email.html \
test_input_range_key_events.html \
test_input_url.html \
test_pattern_attribute.html \
test_required_attribute.html \

View File

@@ -0,0 +1,206 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=843725
-->
<head>
<title>Test key events for range</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<meta charset="UTF-8">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=843725">Mozilla Bug 843725</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script type="application/javascript">
/**
* Test for Bug 843725
* This test checks how the value of <input type=range> changes in response to
* various key events while it is in various states.
**/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
test();
SimpleTest.finish();
});
const defaultMinimum = 0;
const defaultMaximum = 100;
const defaultStep = 1;
// Helpers:
// For the sake of simplicity, we do not currently support fractional value,
// step, etc.
function minimum(element) {
return Number(element.min || defaultMinimum);
}
function maximum(element) {
return Number(element.max || defaultMaximum);
}
function range(element) {
var max = maximum(element);
var min = minimum(element);
if (max < min) {
return 0;
}
return max - min;
}
function defaultValue(element) {
return minimum(element) + range(element)/2;
}
function value(element) {
return Number(element.value || defaultValue(element));
}
function step(element) {
var step = Number(element.step || defaultStep);
return step <= 0 ? defaultStep : step;
}
function clampToRange(value, element) {
var min = minimum(element);
var max = maximum(element);
if (max < min) {
return min;
}
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}
// Functions used to specify expected test results:
function valuePlusStep(element) {
return clampToRange(value(element) + step(element), element);
}
function valueMinusStep(element) {
return clampToRange(value(element) - step(element), element);
}
/**
* Returns the current value of the range plus whichever is greater of either
* 10% of the range or its current step value, clamped to the range's minimum/
* maximum. The reason for using the step if it is greater than 10% of the
* range is because otherwise the PgUp/PgDn keys would do nothing in that case.
*/
function valuePlusTenPctOrStep(element) {
var tenPct = range(element)/10;
var stp = step(element);
return clampToRange(value(element) + Math.max(tenPct, stp), element);
}
function valueMinusTenPctOrStep(element) {
var tenPct = range(element)/10;
var stp = step(element);
return clampToRange(value(element) - Math.max(tenPct, stp), element);
}
// Test table:
const LTR = "ltr";
const RTL = "rtl";
var testTable = [
["VK_LEFT", LTR, valueMinusStep],
["VK_LEFT", RTL, valuePlusStep],
["VK_RIGHT", LTR, valuePlusStep],
["VK_RIGHT", RTL, valueMinusStep],
["VK_UP", LTR, valuePlusStep],
["VK_UP", RTL, valuePlusStep],
["VK_DOWN", LTR, valueMinusStep],
["VK_DOWN", RTL, valueMinusStep],
["VK_PAGE_UP", LTR, valuePlusTenPctOrStep],
["VK_PAGE_UP", RTL, valuePlusTenPctOrStep],
["VK_PAGE_DOWN", LTR, valueMinusTenPctOrStep],
["VK_PAGE_DOWN", RTL, valueMinusTenPctOrStep],
["VK_HOME", LTR, minimum],
["VK_HOME", RTL, minimum],
["VK_END", LTR, maximum],
["VK_END", RTL, maximum],
]
function test() {
var elem = document.createElement("input");
elem.type = "range";
var content = document.getElementById("content");
content.appendChild(elem);
elem.focus();
for (test of testTable) {
var [key, dir, expectedFunc] = test;
var oldVal, expectedVal;
elem.step = "2";
elem.style.direction = dir;
var flush = document.body.clientWidth;
// Start at middle:
elem.value = oldVal = defaultValue(elem);
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for " + dir + " range with value set to the midpoint (" + oldVal + ")");
// Same again:
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test repeat of " + key + " for " + dir + " range");
// Start at maximum:
elem.value = oldVal = maximum(elem);
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for " + dir + " range with value set to the maximum (" + oldVal + ")");
// Same again:
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test repeat of " + key + " for " + dir + " range");
// Start at minimum:
elem.value = oldVal = minimum(elem);
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for " + dir + " range with value set to the minimum (" + oldVal + ")");
// Same again:
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test repeat of " + key + " for " + dir + " range");
// Test for a step value that is greater than 10% of the range:
elem.step = 20;
elem.value = 60;
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for " + dir + " range with a step that is greater than 10% of the range (step=" + elem.step + ")");
// Same again:
expectedVal = expectedFunc(elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test repeat of " + key + " for " + dir + " range");
// reset step:
elem.step = 2;
}
}
</script>
</pre>
</body>
</html>

View File

@@ -17,7 +17,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478251
<pre id="test">
<script type="application/javascript">
SimpleTest.expectAssertions(10);
SimpleTest.expectAssertions(9, 10);
/** Test for Bug 478251 **/
var doc = $("t").contentDocument;

View File

@@ -31,7 +31,7 @@ if (navigator.platform.startsWith("Win")) {
} else {
// This is "###!!! ASSERTION: Page read cursor should be inside range: 'mPageOffset <= endOffset'"
// https://bugzilla.mozilla.org/show_bug.cgi?id=846769
SimpleTest.expectAssertions(0, 1);
SimpleTest.expectAssertions(0, 5);
}
const NUM_SEEK_TESTS = 13;

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DOMSVGStringList.h"
#include "DOMSVGTests.h"
#include "mozilla/dom/SVGTests.h"
#include "nsError.h"
#include "nsCOMPtr.h"
#include "nsSVGAttrTearoffTable.h"
@@ -185,7 +185,7 @@ SVGStringList &
DOMSVGStringList::InternalList()
{
if (mIsConditionalProcessingAttribute) {
nsCOMPtr<DOMSVGTests> tests = do_QueryInterface(mElement);
nsCOMPtr<dom::SVGTests> tests = do_QueryInterface(mElement);
return tests->mStringListAttributes[mAttrEnum];
}
return mElement->GetStringListInfo().mStringLists[mAttrEnum];

View File

@@ -30,7 +30,6 @@ CPPSRCS = \
DOMSVGPoint.cpp \
DOMSVGPointList.cpp \
DOMSVGStringList.cpp \
DOMSVGTests.cpp \
DOMSVGTransform.cpp \
DOMSVGTransformList.cpp \
nsDOMSVGZoomEvent.cpp \
@@ -124,6 +123,7 @@ CPPSRCS = \
SVGSymbolElement.cpp \
SVGSVGElement.cpp \
SVGSwitchElement.cpp \
SVGTests.cpp \
SVGTextContentElement.cpp \
SVGTextElement.cpp \
SVGTextPathElement.cpp \
@@ -194,6 +194,7 @@ EXPORTS_mozilla/dom = \
SVGSymbolElement.h \
SVGSVGElement.h \
SVGSwitchElement.h \
SVGTests.h \
SVGTextContentElement.h \
SVGTextElement.h \
SVGTextPathElement.h \

View File

@@ -22,7 +22,7 @@ NS_IMPL_RELEASE_INHERITED(SVGAnimationElement, SVGAnimationElementBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimationElement)
NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement)
NS_INTERFACE_MAP_ENTRY(DOMSVGTests)
NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGTests)
NS_INTERFACE_MAP_END_INHERITING(SVGAnimationElementBase)
// Cycle collection magic -- based on nsSVGUseElement
@@ -89,7 +89,7 @@ SVGAnimationElement::AsElement()
bool
SVGAnimationElement::PassesConditionalProcessingTests()
{
return DOMSVGTests::PassesConditionalProcessingTests();
return SVGTests::PassesConditionalProcessingTests();
}
const nsAttrValue*

View File

@@ -6,7 +6,7 @@
#ifndef mozilla_dom_SVGAnimationElement_h
#define mozilla_dom_SVGAnimationElement_h
#include "DOMSVGTests.h"
#include "mozilla/dom/SVGTests.h"
#include "nsISMILAnimationElement.h"
#include "nsReferencedElement.h"
#include "nsSMILTimedElement.h"
@@ -18,7 +18,7 @@ namespace mozilla {
namespace dom {
class SVGAnimationElement : public SVGAnimationElementBase,
public DOMSVGTests,
public SVGTests,
public nsISMILAnimationElement
{
protected:

View File

@@ -15,7 +15,7 @@ NS_IMPL_ADDREF_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase)
NS_IMPL_RELEASE_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase)
NS_INTERFACE_MAP_BEGIN(SVGGraphicsElement)
NS_INTERFACE_MAP_ENTRY(DOMSVGTests)
NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGTests)
NS_INTERFACE_MAP_END_INHERITING(SVGGraphicsElementBase)
//----------------------------------------------------------------------

View File

@@ -6,8 +6,8 @@
#ifndef mozilla_dom_SVGGraphicsElement_h
#define mozilla_dom_SVGGraphicsElement_h
#include "mozilla/dom/SVGTests.h"
#include "mozilla/dom/SVGTransformableElement.h"
#include "DOMSVGTests.h"
namespace mozilla {
namespace dom {
@@ -15,7 +15,7 @@ namespace dom {
typedef SVGTransformableElement SVGGraphicsElementBase;
class SVGGraphicsElement : public SVGGraphicsElementBase,
public DOMSVGTests
public SVGTests
{
protected:
SVGGraphicsElement(already_AddRefed<nsINodeInfo> aNodeInfo);

View File

@@ -15,19 +15,10 @@ const double radPerDegree = 2.0 * M_PI / 360.0;
namespace mozilla {
namespace dom {
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(SVGMatrix, mTransform)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGMatrix)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGMatrix)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGMatrix)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGMatrix) // pseudo-interface
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(SVGMatrix, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(SVGMatrix, Release)
DOMSVGTransform*
SVGMatrix::GetParentObject() const
@@ -122,7 +113,7 @@ SVGMatrix::SetF(float aF, ErrorResult& rv)
already_AddRefed<SVGMatrix>
SVGMatrix::Multiply(SVGMatrix& aMatrix)
{
nsCOMPtr<SVGMatrix> matrix = new SVGMatrix(aMatrix.Matrix() * Matrix());
nsRefPtr<SVGMatrix> matrix = new SVGMatrix(aMatrix.Matrix() * Matrix());
return matrix.forget();
}

View File

@@ -44,28 +44,17 @@
#include "nsWrapperCache.h"
#include "mozilla/Attributes.h"
// We make DOMSVGMatrix a pseudo-interface to allow us to QI to it in order
// to check that the objects that scripts pass in are our *native* matrix
// objects.
//
// {633419E5-7E88-4C3E-8A9A-856F635E90A3}
#define MOZILLA_DOMSVGMATRIX_IID \
{ 0x633419E5, 0x7E88, 0x4C3E, \
{ 0x8A, 0x9A, 0x85, 0x6F, 0x63, 0x5E, 0x90, 0xA3 } }
namespace mozilla {
namespace dom {
/**
* DOM wrapper for an SVG matrix.
*/
class SVGMatrix MOZ_FINAL : public nsISupports,
public nsWrapperCache
class SVGMatrix MOZ_FINAL : public nsWrapperCache
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGMATRIX_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SVGMatrix)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(SVGMatrix)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(SVGMatrix)
/**
* Ctor for SVGMatrix objects that belong to a DOMSVGTransform.
@@ -141,8 +130,6 @@ private:
gfxMatrix mMatrix;
};
NS_DEFINE_STATIC_IID_ACCESSOR(SVGMatrix, MOZILLA_DOMSVGMATRIX_IID)
} // namespace dom
} // namespace mozilla

View File

@@ -6,7 +6,6 @@
#include "mozilla/Util.h"
#include "mozilla/dom/SVGSwitchElement.h"
#include "DOMSVGTests.h"
#include "nsIFrame.h"
#include "nsSVGUtils.h"
#include "mozilla/Preferences.h"
@@ -146,10 +145,10 @@ SVGSwitchElement::FindActiveChild() const
if (!child->IsElement()) {
continue;
}
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child));
nsCOMPtr<SVGTests> tests(do_QueryInterface(child));
if (tests) {
if (tests->PassesConditionalProcessingTests(
DOMSVGTests::kIgnoreSystemLanguage)) {
SVGTests::kIgnoreSystemLanguage)) {
int32_t languagePreferenceRank =
tests->GetBestLanguagePreferenceRank(acceptLangs);
switch (languagePreferenceRank) {
@@ -181,7 +180,7 @@ SVGSwitchElement::FindActiveChild() const
if (!child->IsElement()) {
continue;
}
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child));
nsCOMPtr<SVGTests> tests(do_QueryInterface(child));
if (!tests || tests->PassesConditionalProcessingTests(&acceptLangs)) {
return child;
}

View File

@@ -22,7 +22,7 @@ SVGSymbolElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
NS_IMPL_ISUPPORTS_INHERITED4(SVGSymbolElement, SVGSymbolElementBase,
nsIDOMNode, nsIDOMElement,
nsIDOMSVGElement, DOMSVGTests)
nsIDOMSVGElement, mozilla::dom::SVGTests)
//----------------------------------------------------------------------
// Implementation

View File

@@ -6,7 +6,7 @@
#ifndef mozilla_dom_SVGSymbolElement_h
#define mozilla_dom_SVGSymbolElement_h
#include "DOMSVGTests.h"
#include "mozilla/dom/SVGTests.h"
#include "nsSVGElement.h"
#include "nsSVGViewBox.h"
#include "SVGAnimatedPreserveAspectRatio.h"
@@ -22,7 +22,7 @@ typedef nsSVGElement SVGSymbolElementBase;
class SVGSymbolElement MOZ_FINAL : public SVGSymbolElementBase,
public nsIDOMSVGElement,
public DOMSVGTests
public SVGTests
{
protected:
friend nsresult (::NS_NewSVGSymbolElement(nsIContent **aResult,

View File

@@ -3,7 +3,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/. */
#include "DOMSVGTests.h"
#include "mozilla/dom/SVGTests.h"
#include "DOMSVGStringList.h"
#include "nsSVGFeatures.h"
#include "mozilla/dom/SVGSwitchElement.h"
@@ -11,24 +11,25 @@
#include "nsStyleUtil.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS0(DOMSVGTests)
NS_IMPL_ISUPPORTS0(SVGTests)
nsIAtom** DOMSVGTests::sStringListNames[3] =
nsIAtom** SVGTests::sStringListNames[3] =
{
&nsGkAtoms::requiredFeatures,
&nsGkAtoms::requiredExtensions,
&nsGkAtoms::systemLanguage,
};
DOMSVGTests::DOMSVGTests()
SVGTests::SVGTests()
{
mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true);
}
already_AddRefed<nsIDOMSVGStringList>
DOMSVGTests::RequiredFeatures()
SVGTests::RequiredFeatures()
{
nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
return DOMSVGStringList::GetDOMWrapper(
@@ -36,7 +37,7 @@ DOMSVGTests::RequiredFeatures()
}
already_AddRefed<nsIDOMSVGStringList>
DOMSVGTests::RequiredExtensions()
SVGTests::RequiredExtensions()
{
nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
return DOMSVGStringList::GetDOMWrapper(
@@ -44,7 +45,7 @@ DOMSVGTests::RequiredExtensions()
}
already_AddRefed<nsIDOMSVGStringList>
DOMSVGTests::SystemLanguage()
SVGTests::SystemLanguage()
{
nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
return DOMSVGStringList::GetDOMWrapper(
@@ -52,13 +53,13 @@ DOMSVGTests::SystemLanguage()
}
bool
DOMSVGTests::HasExtension(const nsAString& aExtension)
SVGTests::HasExtension(const nsAString& aExtension)
{
return nsSVGFeatures::HasExtension(aExtension);
}
bool
DOMSVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
SVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
{
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
if (aAttribute == *sStringListNames[i]) {
@@ -69,7 +70,7 @@ DOMSVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
}
int32_t
DOMSVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const
SVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const
{
const nsDefaultStringComparator defaultComparator;
@@ -100,10 +101,10 @@ DOMSVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) cons
return lowestRank;
}
const nsString * const DOMSVGTests::kIgnoreSystemLanguage = (nsString *) 0x01;
const nsString * const SVGTests::kIgnoreSystemLanguage = (nsString *) 0x01;
bool
DOMSVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
SVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
{
// Required Features
if (mStringListAttributes[FEATURES].IsExplicitlySet()) {
@@ -111,7 +112,7 @@ DOMSVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) cons
return false;
}
nsCOMPtr<nsIContent> content(
do_QueryInterface(const_cast<DOMSVGTests*>(this)));
do_QueryInterface(const_cast<SVGTests*>(this)));
for (uint32_t i = 0; i < mStringListAttributes[FEATURES].Length(); i++) {
if (!nsSVGFeatures::HasFeature(content, mStringListAttributes[FEATURES][i])) {
@@ -182,7 +183,7 @@ DOMSVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) cons
}
bool
DOMSVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
SVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
@@ -200,7 +201,7 @@ DOMSVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
}
void
DOMSVGTests::UnsetAttr(const nsIAtom* aAttribute)
SVGTests::UnsetAttr(const nsIAtom* aAttribute)
{
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
if (aAttribute == *sStringListNames[i]) {
@@ -212,13 +213,13 @@ DOMSVGTests::UnsetAttr(const nsIAtom* aAttribute)
}
nsIAtom*
DOMSVGTests::GetAttrName(uint8_t aAttrEnum) const
SVGTests::GetAttrName(uint8_t aAttrEnum) const
{
return *sStringListNames[aAttrEnum];
}
void
DOMSVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const
SVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const
{
MOZ_ASSERT(aAttrEnum < ArrayLength(sStringListNames),
"aAttrEnum out of range");
@@ -226,7 +227,7 @@ DOMSVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const
}
void
DOMSVGTests::MaybeInvalidate()
SVGTests::MaybeInvalidate()
{
nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
@@ -237,3 +238,6 @@ DOMSVGTests::MaybeInvalidate()
static_cast<dom::SVGSwitchElement*>(parent)->MaybeInvalidate();
}
}
} // namespace dom
} // namespace mozilla

View File

@@ -3,8 +3,8 @@
* 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 MOZILLA_DOMSVGTESTS_H__
#define MOZILLA_DOMSVGTESTS_H__
#ifndef mozilla_dom_SVGTests_h
#define mozilla_dom_SVGTests_h
#include "nsStringFwd.h"
#include "SVGStringList.h"
@@ -17,20 +17,21 @@ class nsString;
namespace mozilla {
class DOMSVGStringList;
}
#define MOZILLA_DOMSVGTESTS_IID \
{ 0x92370da8, 0xda28, 0x4895, \
{0x9b, 0x1b, 0xe0, 0x06, 0x0d, 0xb7, 0x3f, 0xc3 } }
class DOMSVGTests : public nsISupports
namespace dom {
class SVGTests : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGTESTS_IID)
NS_DECL_ISUPPORTS
DOMSVGTests();
virtual ~DOMSVGTests() {}
SVGTests();
virtual ~SVGTests() {}
friend class mozilla::DOMSVGStringList;
typedef mozilla::SVGStringList SVGStringList;
@@ -101,6 +102,9 @@ private:
static nsIAtom** sStringListNames[3];
};
NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGTests, MOZILLA_DOMSVGTESTS_IID)
NS_DEFINE_STATIC_IID_ACCESSOR(SVGTests, MOZILLA_DOMSVGTESTS_IID)
#endif // MOZILLA_DOMSVGTESTS_H__
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGTests_h

View File

@@ -190,7 +190,7 @@ SVGTransformableElement::GetCTM()
currentDoc->FlushPendingNotifications(Flush_Layout);
}
gfxMatrix m = SVGContentUtils::GetCTM(this, false);
nsCOMPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m);
nsRefPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m);
return mat.forget();
}
@@ -203,7 +203,7 @@ SVGTransformableElement::GetScreenCTM()
currentDoc->FlushPendingNotifications(Flush_Layout);
}
gfxMatrix m = SVGContentUtils::GetCTM(this, true);
nsCOMPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m);
nsRefPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m);
return mat.forget();
}
@@ -212,16 +212,16 @@ SVGTransformableElement::GetTransformToElement(SVGGraphicsElement& aElement,
ErrorResult& rv)
{
// the easiest way to do this (if likely to increase rounding error):
nsCOMPtr<SVGMatrix> ourScreenCTM = GetScreenCTM();
nsCOMPtr<SVGMatrix> targetScreenCTM = aElement.GetScreenCTM();
nsRefPtr<SVGMatrix> ourScreenCTM = GetScreenCTM();
nsRefPtr<SVGMatrix> targetScreenCTM = aElement.GetScreenCTM();
if (!ourScreenCTM || !targetScreenCTM) {
rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
nsCOMPtr<SVGMatrix> tmp = targetScreenCTM->Inverse(rv);
nsRefPtr<SVGMatrix> tmp = targetScreenCTM->Inverse(rv);
if (rv.Failed()) return nullptr;
nsCOMPtr<SVGMatrix> mat = tmp->Multiply(*ourScreenCTM);
nsRefPtr<SVGMatrix> mat = tmp->Multiply(*ourScreenCTM);
return mat.forget();
}

View File

@@ -9,6 +9,7 @@
#include "nsSVGElement.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/dom/SVGTests.h"
#include "nsIDocument.h"
#include "nsRange.h"
#include "nsIDOMAttr.h"
@@ -48,7 +49,6 @@
#include "SVGAnimatedPathSegList.h"
#include "SVGAnimatedTransformList.h"
#include "SVGContentUtils.h"
#include "DOMSVGTests.h"
#include "nsSVGRect.h"
#include "nsIFrame.h"
#include "prdtoa.h"
@@ -545,7 +545,7 @@ nsSVGElement::ParseAttribute(int32_t aNamespaceID,
if (!foundMatch) {
// Check for conditional processing attributes
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
nsCOMPtr<SVGTests> tests(do_QueryInterface(this));
if (tests && tests->ParseConditionalProcessingAttribute(
aAttribute, aValue, aResult)) {
foundMatch = true;
@@ -829,7 +829,7 @@ nsSVGElement::UnsetAttrInternal(int32_t aNamespaceID, nsIAtom* aName,
}
// Check for conditional processing attributes
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
nsCOMPtr<SVGTests> tests(do_QueryInterface(this));
if (tests && tests->IsConditionalProcessingAttribute(aName)) {
MaybeSerializeAttrBeforeRemoval(aName, aNotify);
tests->UnsetAttr(aName);
@@ -880,10 +880,10 @@ nsSVGElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
nsChangeHint retval =
nsSVGElementBase::GetAttributeChangeHint(aAttribute, aModType);
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(const_cast<nsSVGElement*>(this)));
nsCOMPtr<SVGTests> tests(do_QueryInterface(const_cast<nsSVGElement*>(this)));
if (tests && tests->IsConditionalProcessingAttribute(aAttribute)) {
// It would be nice to only reconstruct the frame if the value returned by
// DOMSVGTests::PassesConditionalProcessingTests has changed, but we don't
// SVGTests::PassesConditionalProcessingTests has changed, but we don't
// know that
NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
}
@@ -2447,7 +2447,7 @@ nsSVGElement::WillChangeStringList(bool aIsConditionalProcessingAttribute,
{
nsIAtom* name;
if (aIsConditionalProcessingAttribute) {
nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
nsCOMPtr<SVGTests> tests(do_QueryInterface(this));
name = tests->GetAttrName(aAttrEnum);
} else {
name = *GetStringListInfo().mStringListInfo[aAttrEnum].mName;
@@ -2462,7 +2462,7 @@ nsSVGElement::DidChangeStringList(bool aIsConditionalProcessingAttribute,
{
nsIAtom* name;
nsAttrValue newValue;
nsCOMPtr<DOMSVGTests> tests;
nsCOMPtr<SVGTests> tests;
if (aIsConditionalProcessingAttribute) {
tests = do_QueryInterface(this);

View File

@@ -314,15 +314,15 @@ private:
const nsAString* mStr;
};
// Class for representing sequences in arguments. We use an auto array that can
// hold 16 elements, to avoid having to allocate in common cases. This needs to
// be fallible because web content controls the length of the array, and can
// easily try to create very large lengths.
// Class for representing sequences in arguments. We use a non-auto array
// because that allows us to use sequences of sequences and the like. This
// needs to be fallible because web content controls the length of the array,
// and can easily try to create very large lengths.
template<typename T>
class Sequence : public AutoFallibleTArray<T, 16>
class Sequence : public FallibleTArray<T>
{
public:
Sequence() : AutoFallibleTArray<T, 16>()
Sequence() : FallibleTArray<T>()
{}
};

View File

@@ -1558,6 +1558,20 @@ public:
}
};
// Class for simple sequence arguments, only used internally by codegen.
template<typename T>
class AutoSequence : public AutoFallibleTArray<T, 16>
{
public:
AutoSequence() : AutoFallibleTArray<T, 16>()
{}
// Allow converting to const sequences as needed
operator const Sequence<T>&() const {
return *reinterpret_cast<const Sequence<T>*>(this);
}
};
inline bool
IdEquals(jsid id, const char* string)
{

View File

@@ -11,12 +11,12 @@
# Valid fields for all descriptors:
# * nativeType - The native type (concrete class or XPCOM interface) that
# instances of this interface will unwrap to. If not
# specified, defaults to "mozilla::dom::InterfaceName" for
# specified, defaults to 'mozilla::dom::InterfaceName' for
# non-worker non-external-or-callback interfaces, to
# "mozilla::dom::workers::InterfaceName" for worker
# 'mozilla::dom::workers::InterfaceName' for worker
# non-external interfaces, to 'nsIDOM' followed by the
# interface name for non-worker external-or-callback
# interfaces, and to "JSObject" for worker external-or-callback
# interfaces, and to 'JSObject' for worker external-or-callback
# interfaces.
# * headerFile - The file in which the nativeType is declared (defaults
# to an educated guess).
@@ -53,9 +53,9 @@
# interfaces. Defaults to true for non-worker non-callback
# descriptors.
# * nativeOwnership: Describes how the native object is held. 4 possible
# types: worker object ("worker"), non-refcounted object
# ("owned"), refcounted non-nsISupports object
# ("refcounted") or nsISupports ("nsisupports").
# types: worker object ('worker'), non-refcounted object
# ('owned'), refcounted non-nsISupports object
# ('refcounted') or nsISupports ('nsisupports').
# Non-refcounted objects need to inherit from
# mozilla::dom::NonRefcountedDOMObject and preferably use
# MOZ_COUNT_CTOR/MOZ_COUNT_DTOR in their
@@ -67,8 +67,8 @@
# call delete through XPConnect's deferred finalization
# mechanism, for a refcounted object it'll call Release
# through XPConnect's deferred finalization mechanism.
# Always "worker" for worker descriptors. Defaults to
# "nsisupports".
# Always 'worker' for worker descriptors. Defaults to
# 'nsisupports'.
#
# The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and
@@ -171,21 +171,21 @@ DOMInterfaces = {
'nativeType': 'nsDOMCSSDeclaration'
},
"CSSPrimitiveValue": {
"nativeType": "nsROCSSPrimitiveValue",
"resultNotAddRefed": ["getRGBColorValue", "getRectValue"]
'CSSPrimitiveValue': {
'nativeType': 'nsROCSSPrimitiveValue',
'resultNotAddRefed': ['getRGBColorValue', 'getRectValue']
},
'CSSStyleDeclaration': {
'nativeType': 'nsICSSDeclaration'
},
"CSSValue": {
"concrete": False
'CSSValue': {
'concrete': False
},
"CSSValueList": {
"nativeType": "nsDOMCSSValueList"
'CSSValueList': {
'nativeType': 'nsDOMCSSValueList'
},
'DelayNode': [
@@ -583,14 +583,14 @@ DOMInterfaces = {
},
'Rect': {
"nativeType": "nsDOMCSSRect",
'resultNotAddRefed': [ "top", "right", "bottom", "left" ]
'nativeType': 'nsDOMCSSRect',
'resultNotAddRefed': [ 'top', 'right', 'bottom', 'left' ]
},
'RGBColor': {
"nativeOwnership": "refcounted",
"nativeType": "nsDOMCSSRGBColor",
'resultNotAddRefed': [ "alpha", "blue", "green", "red" ]
'nativeOwnership': 'refcounted',
'nativeType': 'nsDOMCSSRGBColor',
'resultNotAddRefed': [ 'alpha', 'blue', 'green', 'red' ]
},
'Screen': {
@@ -667,6 +667,10 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/SVGGradientElement.h',
},
'SVGMatrix' : {
'nativeOwnership': 'refcounted'
},
'SVGNumberList': {
'nativeType': 'mozilla::DOMSVGNumberList',
'headerFile': 'DOMSVGNumberList.h',
@@ -1198,7 +1202,7 @@ addExternalIface('Attr')
addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('ClientRect')
addExternalIface("Counter")
addExternalIface('Counter')
addExternalIface('CSSRule')
addExternalIface('DOMRequest')
addExternalIface('DOMStringList')

View File

@@ -2098,27 +2098,6 @@ ${codeOnFailure}
}
${target} = tmp.forget();""").substitute(self.substitution)
def dictionaryHasSequenceMember(dictionary):
return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
dictionary.members) or
(dictionary.parent and
dictionaryHasSequenceMember(dictionary.parent)))
def typeIsSequenceOrHasSequenceMember(type):
if type.nullable():
type = type.inner
if type.isSequence():
return True
if type.isArray():
elementType = type.inner
return typeIsSequenceOrHasSequenceMember(elementType)
if type.isDictionary():
return dictionaryHasSequenceMember(type.inner)
if type.isUnion():
return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
type.flatMemberTypes)
return False
# If this function is modified, modify CGNativeMember.getArg and
# CGNativeMember.getRetvalInfo accordingly. The latter cares about the decltype
# and holdertype we end up using.
@@ -2154,9 +2133,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if isMember is True, we're being converted from a property of some
JS object, not from an actual method argument, so we can't rely on
our jsval being rooted or outliving us in any way. Any caller
passing true needs to ensure that it is handled correctly in
typeIsSequenceOrHasSequenceMember.
our jsval being rooted or outliving us in any way.
If isOptional is true, then we are doing conversion of an optional
argument with no default value.
@@ -2326,21 +2303,25 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
else:
elementType = type.inner
# We have to be careful with reallocation behavior for arrays. In
# particular, if we have a sequence of elements which are themselves
# sequences (so nsAutoTArrays) or have sequences as members, we have a
# problem. In that case, resizing the outermost nsAutoTarray to the
# right size will memmove its elements, but nsAutoTArrays are not
# memmovable and hence will end up with pointers to bogus memory, which
# is bad. To deal with this, we disallow sequences, arrays,
# dictionaries, and unions which contain sequences as sequence item
# types. If WebIDL ever adds another container type, we'd have to
# disallow it as well.
if typeIsSequenceOrHasSequenceMember(elementType):
raise TypeError("Can't handle a sequence containing another "
"sequence as an element or member of an element. "
"See the big comment explaining why.\n%s" %
str(type.location))
# We want to use auto arrays if we can, but we have to be careful with
# reallocation behavior for arrays. In particular, if we use auto
# arrays for sequences and have a sequence of elements which are
# themselves sequences or have sequences as members, we have a problem.
# In that case, resizing the outermost nsAutoTarray to the right size
# will memmove its elements, but nsAutoTArrays are not memmovable and
# hence will end up with pointers to bogus memory, which is bad. To
# deal with this, we typically map WebIDL sequences to our Sequence
# type, which is in fact memmovable. The one exception is when we're
# passing in a sequence directly as an argument without any sort of
# optional or nullable complexity going on. In that situation, we can
# use an AutoSequence instead. We have to keep using Sequence in the
# nullable and optional cases because we don't want to leak the
# AutoSequence type to consumers, which would be unavoidable with
# Nullable<AutoSequence> or Optional<AutoSequence>.
if isMember or isOptional or nullable:
sequenceClass = "Sequence"
else:
sequenceClass = "AutoSequence"
(elementTemplate, elementDeclType,
elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
@@ -2351,15 +2332,18 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if elementHolderType is not None:
raise TypeError("Shouldn't need holders for sequences")
typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >")
typeName = CGWrapper(elementDeclType,
pre=("%s< " % sequenceClass), post=" >")
sequenceType = typeName.define()
if nullable:
typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
arrayRef = "${declName}.Value()"
else:
arrayRef = "${declName}"
# If we're optional, the const will come from the Optional
# If we're optional or a member, the const will come from the Optional
# or whatever we're a member of.
mutableTypeName = typeName
if not isOptional:
if not isOptional and not isMember:
typeName = CGWrapper(typeName, pre="const ")
# NOTE: Keep this in sync with variadic conversions as needed
@@ -2372,7 +2356,7 @@ uint32_t length;
if (!JS_GetArrayLength(cx, seq, &length)) {
%s
}
Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
%s &arr = const_cast< %s& >(%s);
if (!arr.SetCapacity(length)) {
JS_ReportOutOfMemory(cx);
%s
@@ -2385,8 +2369,8 @@ for (uint32_t i = 0; i < length; ++i) {
%s& slot = *arr.AppendElement();
""" % (CGIndenter(CGGeneric(notSequence)).define(),
exceptionCodeIndented.define(),
elementDeclType.define(),
elementDeclType.define(),
sequenceType,
sequenceType,
arrayRef,
exceptionCodeIndented.define(),
CGIndenter(exceptionCodeIndented).define(),
@@ -3327,7 +3311,7 @@ class CGArgumentConverter(CGThing):
raise TypeError("Shouldn't need holders for variadics")
replacer = dict(self.argcAndIndex, **self.replacementVariables)
replacer["seqType"] = CGWrapper(elementDeclType, pre="Sequence< ", post=" >").define()
replacer["seqType"] = CGWrapper(elementDeclType, pre="AutoSequence< ", post=" >").define()
replacer["elemType"] = elementDeclType.define()
# NOTE: Keep this in sync with sequence conversions as needed
@@ -5450,7 +5434,7 @@ class ClassConstructor(ClassItem):
if self.bodyInHeader:
return ''
args = ', '.join([str(a) for a in self.args])
args = ', '.join([a.define() for a in self.args])
body = ' ' + self.getBody()
body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n '))

View File

@@ -337,6 +337,8 @@ public:
void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&);
void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value> >);
void PassSequenceOfSequences(const Sequence< Sequence<int32_t> >&);
// Typed array types
void PassArrayBuffer(ArrayBuffer&);
void PassNullableArrayBuffer(ArrayBuffer*);

View File

@@ -316,6 +316,8 @@ interface TestInterface {
sequence<any> receiveAnySequence();
sequence<any>? receiveNullableAnySequence();
void passSequenceOfSequences(sequence<sequence<long>> arg);
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);

View File

@@ -232,6 +232,8 @@ interface TestExampleInterface {
sequence<any> receiveAnySequence();
sequence<any>? receiveNullableAnySequence();
void passSequenceOfSequences(sequence<sequence<long>> arg);
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);

View File

@@ -274,7 +274,10 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_FALSE_VOID(sStopSendingRingFlag);
// Stop sending RING indicator
if (sStopSendingRingFlag) {
return;
}
if (!gBluetoothHfpManager) {
NS_WARNING("BluetoothHfpManager no longer exists, cannot send ring!");
@@ -1158,6 +1161,9 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
mCurrentCallArray.AppendElement(call);
}
uint16_t prevCallState = mCurrentCallArray[aCallIndex].mState;
mCurrentCallArray[aCallIndex].mState = aCallState;
// Same logic as implementation in ril_worker.js
if (aNumber.Length() && aNumber[0] == '+') {
mCurrentCallArray[aCallIndex].mType = TOA_INTERNATIONAL;
@@ -1166,7 +1172,6 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
nsRefPtr<nsRunnable> sendRingTask;
nsString address;
uint16_t prevCallState = mCurrentCallArray[aCallIndex].mState;
uint32_t callArrayLength = mCurrentCallArray.Length();
uint32_t index = 1;
@@ -1283,10 +1288,6 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
}
if (aCallIndex == mCurrentCallIndex) {
NS_ASSERTION(mCurrentCallArray.Length() > aCallIndex,
"Call index out of bounds!");
mCurrentCallArray[aCallIndex].mState = aCallState;
// Find the first non-disconnected call (like connected, held),
// and update mCurrentCallIndex
while (index < callArrayLength) {
@@ -1311,8 +1312,6 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
sCINDItems[CINDType::CALLSETUP].value = CallSetupState::NO_CALLSETUP;
sCINDItems[CINDType::CALLHELD].value = CallHeldState::NO_CALLHELD;
}
mCurrentCallArray[aCallIndex].mState = aCallState;
}
void

View File

@@ -619,18 +619,6 @@ bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
}
MaybeForwardEventToRenderFrame(event, &e);
// Adjust the widget coordinates to be relative to our frame.
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
// No frame anymore?
sEventCapturer = nullptr;
return false;
}
nsEventStateManager::MapEventCoordinatesForChildProcess(frameLoader, &event);
return (e.message == NS_TOUCH_MOVE) ?
PBrowserParent::SendRealTouchMoveEvent(e) :
PBrowserParent::SendRealTouchEvent(e);
@@ -667,6 +655,17 @@ TabParent::TryCapture(const nsGUIEvent& aEvent)
return false;
}
// Adjust the widget coordinates to be relative to our frame.
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
// No frame anymore?
sEventCapturer = nullptr;
return false;
}
nsEventStateManager::MapEventCoordinatesForChildProcess(frameLoader, &event);
SendRealTouchEvent(event);
return true;
}

View File

@@ -629,14 +629,7 @@ nsEditor::GetSelection()
nsresult res = GetSelection(getter_AddRefs(sel));
NS_ENSURE_SUCCESS(res, nullptr);
nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(sel);
NS_ENSURE_TRUE(selPrivate, nullptr);
nsRefPtr<nsFrameSelection> frameSel;
res = selPrivate->GetFrameSelection(getter_AddRefs(frameSel));
NS_ENSURE_SUCCESS(res, nullptr);
return frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
return static_cast<Selection*>(sel.get());
}
NS_IMETHODIMP

View File

@@ -12,7 +12,7 @@
#include "nsIDOMNode.h"
#include "nsIEditor.h"
#include "nsIPresShell.h"
#include "nsISelection.h"
#include "mozilla/Selection.h"
#include "nsISelectionPrivate.h"
#include "nsISupportsImpl.h"
#include "nsPlaintextEditor.h"
@@ -20,6 +20,8 @@
#include "nsTextEditRules.h"
#include "nscore.h"
using namespace mozilla;
// Test for distance between caret and text that will be deleted
nsresult
nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection,
@@ -45,12 +47,8 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection,
uint8_t levelBefore;
uint8_t levelAfter;
nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryInterface(aSelection));
NS_ENSURE_TRUE(privateSelection, NS_ERROR_NULL_POINTER);
nsRefPtr<nsFrameSelection> frameSelection;
privateSelection->GetFrameSelection(getter_AddRefs(frameSelection));
nsRefPtr<nsFrameSelection> frameSelection =
static_cast<Selection*>(aSelection)->GetFrameSelection();
NS_ENSURE_TRUE(frameSelection, NS_ERROR_NULL_POINTER);
nsPrevNextBidiLevels levels = frameSelection->

Some files were not shown because too many files have changed in this diff Show More