Merge central to inbound
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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']
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
60
build/mach_bootstrap.py
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
206
content/html/content/test/forms/test_input_range_key_events.html
Normal file
206
content/html/content/test/forms/test_input_range_key_events.html
Normal 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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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 '))
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user