Merge from mozilla-central.
Merge from mozilla-central.
--- a/accessible/src/msaa/DocAccessibleWrap.cpp
+++ b/accessible/src/msaa/DocAccessibleWrap.cpp
@@ -253,17 +253,17 @@ DocAccessibleWrap::DoInitialUpdate()
if (nsWinUtils::IsWindowEmulationStarted()) {
// Create window for tab document.
if (nsCoreUtils::IsTabDocument(mDocument)) {
mozilla::dom::TabChild* tabChild =
mozilla::dom::GetTabChildFrom(mDocument->GetShell());
a11y::RootAccessible* rootDocument = RootAccessible();
- mozilla::WindowsHandle nativeData = nsnull;
+ mozilla::WindowsHandle nativeData = NULL;
if (tabChild)
tabChild->SendGetWidgetNativeData(&nativeData);
else
nativeData = reinterpret_cast<mozilla::WindowsHandle>(
rootDocument->GetNativeWindow());
bool isActive = true;
PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
--- a/b2g/chrome/content/dbg-browser-actors.js
+++ b/b2g/chrome/content/dbg-browser-actors.js
@@ -1,15 +1,19 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */
'use strict';
+/**
+ * B2G-specific actors that extend BrowserRootActor and BrowserTabActor,
+ * overriding some of their methods.
+ */
/**
* The function that creates the root actor. DebuggerServer expects to find this
* function in the loaded actors in order to initialize properly.
*/
function createRootActor(connection) {
return new DeviceRootActor(connection);
}
@@ -19,77 +23,62 @@ function createRootActor(connection) {
* The root actor is responsible for the initial 'hello' packet and for
* responding to a 'listTabs' request that produces the list of currently open
* tabs.
*
* @param connection DebuggerServerConnection
* The conection to the client.
*/
function DeviceRootActor(connection) {
- this.conn = connection;
- this._tabActors = new WeakMap();
- this._tabActorPool = null;
- this._actorFactories = null;
+ BrowserRootActor.call(this, connection);
this.browser = Services.wm.getMostRecentWindow('navigator:browser');
}
-DeviceRootActor.prototype = {
- /**
- * Return a 'hello' packet as specified by the Remote Debugging Protocol.
- */
- sayHello: function DRA_sayHello() {
- return {
- from: 'root',
- applicationType: 'browser',
- traits: []
- };
- },
+DeviceRootActor.prototype = new BrowserRootActor();
- /**
- * Disconnects the actor from the browser window.
- */
- disconnect: function DRA_disconnect() {
- let actor = this._tabActors.get(this.browser);
- if (actor) {
- actor.exit();
- }
- },
+/**
+ * Disconnects the actor from the browser window.
+ */
+DeviceRootActor.prototype.disconnect = function DRA_disconnect() {
+ let actor = this._tabActors.get(this.browser);
+ if (actor) {
+ actor.exit();
+ }
+};
- /**
- * Handles the listTabs request. Builds a list of actors for the single
- * tab (window) running in the process. The actors will survive
- * until at least the next listTabs request.
- */
- onListTabs: function DRA_onListTabs() {
- let actor = this._tabActors.get(this.browser);
- if (!actor) {
- actor = new DeviceTabActor(this.conn, this.browser);
- // this.actorID is set by ActorPool when an actor is put into one.
- actor.parentID = this.actorID;
- this._tabActors.set(this.browser, actor);
- }
-
- let actorPool = new ActorPool(this.conn);
- actorPool.addActor(actor);
-
- // Now drop the old actorID -> actor map. Actors that still mattered were
- // added to the new map, others will go away.
- if (this._tabActorPool) {
- this.conn.removeActorPool(this._tabActorPool);
- }
- this._tabActorPool = actorPool;
- this.conn.addActorPool(this._tabActorPool);
-
- return {
- 'from': 'root',
- 'selected': 0,
- 'tabs': [actor.grip()]
- };
+/**
+ * Handles the listTabs request. Builds a list of actors for the single
+ * tab (window) running in the process. The actors will survive
+ * until at least the next listTabs request.
+ */
+DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
+ let actor = this._tabActors.get(this.browser);
+ if (!actor) {
+ actor = new DeviceTabActor(this.conn, this.browser);
+ // this.actorID is set by ActorPool when an actor is put into one.
+ actor.parentID = this.actorID;
+ this._tabActors.set(this.browser, actor);
}
+ let actorPool = new ActorPool(this.conn);
+ actorPool.addActor(actor);
+
+ // Now drop the old actorID -> actor map. Actors that still mattered were
+ // added to the new map, others will go away.
+ if (this._tabActorPool) {
+ this.conn.removeActorPool(this._tabActorPool);
+ }
+ this._tabActorPool = actorPool;
+ this.conn.addActorPool(this._tabActorPool);
+
+ return {
+ 'from': 'root',
+ 'selected': 0,
+ 'tabs': [actor.grip()]
+ };
};
/**
* The request types this actor can handle.
*/
DeviceRootActor.prototype.requestTypes = {
'listTabs': DeviceRootActor.prototype.onListTabs
};
@@ -99,224 +88,63 @@ DeviceRootActor.prototype.requestTypes =
* and detaching.
*
* @param connection DebuggerServerConnection
* The connection to the client.
* @param browser browser
* The browser instance that contains this tab.
*/
function DeviceTabActor(connection, browser) {
- this.conn = connection;
- this._browser = browser;
+ BrowserTabActor.call(this, connection, browser);
}
-DeviceTabActor.prototype = {
- get browser() {
- return this._browser;
- },
-
- get exited() {
- return !this.browser;
- },
-
- get attached() {
- return !!this._attached
- },
-
- _tabPool: null,
- get tabActorPool() {
- return this._tabPool;
- },
-
- _contextPool: null,
- get contextActorPool() {
- return this._contextPool;
- },
-
- /**
- * Add the specified breakpoint to the default actor pool connection, in order
- * to be alive as long as the server is.
- *
- * @param BreakpointActor actor
- * The actor object.
- */
- addToBreakpointPool: function DTA_addToBreakpointPool(actor) {
- this.conn.addActor(actor);
- },
-
- /**
- * Remove the specified breakpint from the default actor pool.
- *
- * @param string actor
- * The actor ID.
- */
- removeFromBreakpointPool: function DTA_removeFromBreakpointPool(actor) {
- this.conn.removeActor(actor);
- },
-
- actorPrefix: 'tab',
-
- grip: function DTA_grip() {
- dbg_assert(!this.exited,
- 'grip() should not be called on exited browser actor.');
- dbg_assert(this.actorID,
- 'tab should have an actorID.');
- return {
- 'actor': this.actorID,
- 'title': this.browser.title,
- 'url': this.browser.document.documentURI
- }
- },
-
- /**
- * Called when the actor is removed from the connection.
- */
- disconnect: function DTA_disconnect() {
- this._detach();
- },
-
- /**
- * Called by the root actor when the underlying tab is closed.
- */
- exit: function DTA_exit() {
- if (this.exited) {
- return;
- }
-
- if (this.attached) {
- this._detach();
- this.conn.send({
- 'from': this.actorID,
- 'type': 'tabDetached'
- });
- }
-
- this._browser = null;
- },
-
- /**
- * Does the actual work of attaching to a tab.
- */
- _attach: function DTA_attach() {
- if (this._attached) {
- return;
- }
-
- // Create a pool for tab-lifetime actors.
- dbg_assert(!this._tabPool, 'Should not have a tab pool if we were not attached.');
- this._tabPool = new ActorPool(this.conn);
- this.conn.addActorPool(this._tabPool);
-
- // ... and a pool for context-lifetime actors.
- this._pushContext();
+DeviceTabActor.prototype = new BrowserTabActor();
- this._attached = true;
- },
-
- /**
- * Creates a thread actor and a pool for context-lifetime actors. It then sets
- * up the content window for debugging.
- */
- _pushContext: function DTA_pushContext() {
- dbg_assert(!this._contextPool, "Can't push multiple contexts");
-
- this._contextPool = new ActorPool(this.conn);
- this.conn.addActorPool(this._contextPool);
-
- this.threadActor = new ThreadActor(this);
- this._addDebuggees(this.browser.wrappedJSObject);
- this._contextPool.addActor(this.threadActor);
- },
-
- /**
- * Add the provided window and all windows in its frame tree as debuggees.
- */
- _addDebuggees: function DTA__addDebuggees(content) {
- this.threadActor.addDebuggee(content);
- let frames = content.frames;
- for (let i = 0; i < frames.length; i++) {
- this._addDebuggees(frames[i]);
- }
- },
-
- /**
- * Exits the current thread actor and removes the context-lifetime actor pool.
- * The content window is no longer being debugged after this call.
- */
- _popContext: function DTA_popContext() {
- dbg_assert(!!this._contextPool, 'No context to pop.');
-
- this.conn.removeActorPool(this._contextPool);
- this._contextPool = null;
- this.threadActor.exit();
- this.threadActor = null;
- },
-
- /**
- * Does the actual work of detaching from a tab.
- */
- _detach: function DTA_detach() {
- if (!this.attached) {
- return;
- }
-
- this._popContext();
-
- // Shut down actors that belong to this tab's pool.
- this.conn.removeActorPool(this._tabPool);
- this._tabPool = null;
-
- this._attached = false;
- },
-
- // Protocol Request Handlers
-
- onAttach: function DTA_onAttach(aRequest) {
- if (this.exited) {
- return { type: 'exited' };
- }
-
- this._attach();
-
- return { type: 'tabAttached', threadActor: this.threadActor.actorID };
- },
-
- onDetach: function DTA_onDetach(aRequest) {
- if (!this.attached) {
- return { error: 'wrongState' };
- }
-
- this._detach();
-
- return { type: 'detached' };
- },
-
- /**
- * Prepare to enter a nested event loop by disabling debuggee events.
- */
- preNest: function DTA_preNest() {
- let windowUtils = this.browser
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- windowUtils.suppressEventHandling(true);
- windowUtils.suspendTimeouts();
- },
-
- /**
- * Prepare to exit a nested event loop by enabling debuggee events.
- */
- postNest: function DTA_postNest(aNestData) {
- let windowUtils = this.browser
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- windowUtils.resumeTimeouts();
- windowUtils.suppressEventHandling(false);
+DeviceTabActor.prototype.grip = function DTA_grip() {
+ dbg_assert(!this.exited,
+ 'grip() should not be called on exited browser actor.');
+ dbg_assert(this.actorID,
+ 'tab should have an actorID.');
+ return {
+ 'actor': this.actorID,
+ 'title': this.browser.title,
+ 'url': this.browser.document.documentURI
}
-
};
/**
- * The request types this actor can handle.
+ * Creates a thread actor and a pool for context-lifetime actors. It then sets
+ * up the content window for debugging.
+ */
+DeviceTabActor.prototype._pushContext = function DTA_pushContext() {
+ dbg_assert(!this._contextPool, "Can't push multiple contexts");
+
+ this._contextPool = new ActorPool(this.conn);
+ this.conn.addActorPool(this._contextPool);
+
+ this.threadActor = new ThreadActor(this);
+ this._addDebuggees(this.browser.wrappedJSObject);
+ this._contextPool.addActor(this.threadActor);
+};
+
+// Protocol Request Handlers
+
+/**
+ * Prepare to enter a nested event loop by disabling debuggee events.
*/
-DeviceTabActor.prototype.requestTypes = {
- 'attach': DeviceTabActor.prototype.onAttach,
- 'detach': DeviceTabActor.prototype.onDetach
+DeviceTabActor.prototype.preNest = function DTA_preNest() {
+ let windowUtils = this.browser
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ windowUtils.suppressEventHandling(true);
+ windowUtils.suspendTimeouts();
};
+
+/**
+ * Prepare to exit a nested event loop by enabling debuggee events.
+ */
+DeviceTabActor.prototype.postNest = function DTA_postNest(aNestData) {
+ let windowUtils = this.browser
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ windowUtils.resumeTimeouts();
+ windowUtils.suppressEventHandling(false);
+};
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -539,16 +539,17 @@ var WebappsHelper = {
}
}
// Start the debugger server.
function startDebugger() {
if (!DebuggerServer.initialized) {
// Allow remote connections.
DebuggerServer.init(function () { return true; });
+ DebuggerServer.addBrowserActors();
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
}
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
try {
DebuggerServer.openListener(port);
} catch (e) {
dump('Unable to start debugger server: ' + e + '\n');
@@ -608,8 +609,28 @@ Services.obs.addObserver(function Conten
name: 'view',
data: {
type: handler.type,
url: handler.url
}
});
}, 'content-handler', false);
+(function geolocationStatusTracker() {
+ let gGeolocationActiveCount = 0;
+
+ Services.obs.addObserver(function(aSubject, aTopic, aData) {
+ let oldCount = gGeolocationActiveCount;
+ if (aData == "starting") {
+ gGeolocationActiveCount += 1;
+ } else if (aData == "shutdown") {
+ gGeolocationActiveCount -= 1;
+ }
+
+ // We need to track changes from 1 <-> 0
+ if (gGeolocationActiveCount + oldCount == 1) {
+ shell.sendChromeEvent({
+ type: 'geolocation-status',
+ active: (gGeolocationActiveCount == 1)
+ });
+ }
+}, "geolocation-device-events", false);
+})();
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -327,30 +327,30 @@
key="key_openAddons"/>
<splitmenu id="appmenu_customize"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd2.label;"
#endif
oncommand="openPreferences();">
- <menuitem id="appmenu_socialToggle"
- type="checkbox"
- autocheck="false"
- command="Social:Toggle"/>
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
<menuitem id="appmenu_preferences"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd2.label;"
#endif
oncommand="openPreferences();"/>
<menuseparator/>
+ <menuitem id="appmenu_socialToggle"
+ type="checkbox"
+ autocheck="false"
+ command="Social:Toggle"/>
<menuseparator id="appmenu_toggleToolbarsSeparator"/>
<menuitem id="appmenu_toggleTabsOnTop"
label="&viewTabsOnTop.label;"
type="checkbox"
command="cmd_ToggleTabsOnTop"/>
<menuitem id="appmenu_toolbarLayout"
label="&appMenuToolbarLayout.label;"
command="cmd_CustomizeToolbars"/>
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -83,27 +83,28 @@
<command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
<command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
- <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();"/>
+ <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/>
<command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focus();" disabled="true"/>
<command id="Tools:WebConsole" oncommand="HUDConsoleUI.toggleHUD();"/>
- <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();"/>
- <command id="Tools:Debugger" oncommand="DebuggerUI.toggleDebugger();"/>
- <command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();"/>
- <command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();"/>
- <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();"/>
- <command id="Tools:StyleEditor" oncommand="StyleEditor.toggle();"/>
- <command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();"/>
+ <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true" hidden="true"/>
+ <command id="Tools:Debugger" oncommand="DebuggerUI.toggleDebugger();" disabled="true" hidden="true"/>
+ <command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();" disabled="true" hidden="true"/>
+ <command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();" disabled="true" hidden="true"/>
+ <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true" hidden="true"/>
+ <command id="Tools:StyleEditor" oncommand="StyleEditor.toggle();" disabled="true" hidden="true"/>
+ <command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true" hidden="true"/>
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
+ <command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
<command id="Tools:Sanitize"
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
<command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
@@ -185,69 +186,60 @@
<broadcaster id="workOfflineMenuitemState"/>
<broadcaster id="socialSidebarBroadcaster" hidden="true"/>
<!-- DevTools broadcasters -->
<broadcaster id="devtoolsMenuBroadcaster_DevToolbar"
label="&devToolbarMenu.label;"
type="checkbox" autocheck="false"
command="Tools:DevToolbar"
- key="key_devToolbar"
- disabled="true" hidden="true"/>
+ key="key_devToolbar"/>
<broadcaster id="devtoolsMenuBroadcaster_WebConsole"
label="&webConsoleCmd.label;"
type="checkbox" autocheck="false"
key="key_webConsole"
command="Tools:WebConsole"/>
<broadcaster id="devtoolsMenuBroadcaster_Inspect"
label="&inspectMenu.label;"
type="checkbox" autocheck="false"
command="Tools:Inspect"
- key="key_inspect"
- disabled="true" hidden="true"/>
+ key="key_inspect"/>
<broadcaster id="devtoolsMenuBroadcaster_Debugger"
label="&debuggerMenu.label2;"
type="checkbox" autocheck="false"
command="Tools:Debugger"
- key="key_debugger"
- disabled="true" hidden="true"/>
+ key="key_debugger"/>
<broadcaster id="devtoolsMenuBroadcaster_RemoteDebugger"
label="&remoteDebuggerMenu.label;"
- command="Tools:RemoteDebugger"
- disabled="true" hidden="true"/>
+ command="Tools:RemoteDebugger"/>
<broadcaster id="devtoolsMenuBroadcaster_ChromeDebugger"
label="&chromeDebuggerMenu.label;"
- command="Tools:ChromeDebugger"
- disabled="true" hidden="true"/>
+ command="Tools:ChromeDebugger"/>
<broadcaster id="devtoolsMenuBroadcaster_Scratchpad"
label="&scratchpad.label;"
command="Tools:Scratchpad"
- key="key_scratchpad"
- disabled="true" hidden="true"/>
+ key="key_scratchpad"/>
<broadcaster id="devtoolsMenuBroadcaster_StyleEditor"
label="&styleeditor.label;"
type="checkbox" autocheck="false"
command="Tools:StyleEditor"
- key="key_styleeditor"
- disabled="true" hidden="true"/>
+ key="key_styleeditor"/>
<broadcaster id="devtoolsMenuBroadcaster_ResponsiveUI"
label="&responsiveDesignTool.label;"
type="checkbox" autocheck="false"
command="Tools:ResponsiveUI"
- key="key_responsiveUI"
- disabled="true" hidden="true"/>
+ key="key_responsiveUI"/>
<broadcaster id="devtoolsMenuBroadcaster_PageSource"
label="&pageSourceCmd.label;"
key="key_viewSource"
command="View:PageSource"/>
<broadcaster id="devtoolsMenuBroadcaster_ErrorConsole"
- hidden="true"
label="&errorConsoleCmd.label;"
key="key_errorConsole"
- oncommand="toJavaScriptConsole();"/>
+ command="Tools:ErrorConsole"/>
<broadcaster id="devtoolsMenuBroadcaster_GetMoreTools"
label="&getMoreDevtoolsCmd.label;"
oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/>
</broadcasterset>
<keyset id="mainKeyset">
<key id="key_newNavigator"
key="&newNavigatorCmd.key;"
@@ -287,17 +279,17 @@
#endif
#ifdef XP_GNOME
<key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
<key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>
#else
<key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
#endif
<key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/>
- <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift" disabled="true"/>
+ <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" command="Tools:ErrorConsole" modifiers="accel,shift"/>
<key id="key_devToolbar" keycode="&devToolbar.keycode;" modifiers="shift"
keytext="&devToolbar.keytext;" command="Tools:DevToolbarFocus"/>
<key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();"
#ifdef XP_MACOSX
modifiers="accel,alt"
#else
modifiers="accel,shift"
#endif
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -38,16 +38,17 @@ let SocialUI = {
SocialToolbar.updateButtonHiddenState();
SocialSidebar.updateSidebar();
break;
case "social:ambient-notification-changed":
SocialToolbar.updateButton();
break;
case "social:profile-changed":
SocialToolbar.updateProfile();
+ SocialShareButton.updateProfileInfo();
break;
case "nsPref:changed":
SocialSidebar.updateSidebar();
}
},
get toggleCommand() {
return document.getElementById("Social:Toggle");
@@ -148,17 +149,20 @@ let SocialUI = {
this.notificationPanel.hidePopup();
}
}
let SocialShareButton = {
// Called once, after window load, when the Social.provider object is initialized
init: function SSB_init() {
this.updateButtonHiddenState();
+ this.updateProfileInfo();
+ },
+ updateProfileInfo: function SSB_updateProfileInfo() {
let profileRow = document.getElementById("editSharePopupHeader");
let profile = Social.provider.profile;
if (profile && profile.portrait && profile.displayName) {
profileRow.hidden = false;
let portrait = document.getElementById("socialUserPortrait");
portrait.style.listStyleImage = profile.portrait;
let displayName = document.getElementById("socialUserDisplayName");
displayName.setAttribute("label", profile.displayName);
@@ -369,16 +373,20 @@ var SocialToolbar = {
this.button.setAttribute("open", "true");
panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
}
}
var SocialSidebar = {
// Called once, after window load, when the Social.provider object is initialized
init: function SocialSidebar_init() {
+ let sbrowser = document.getElementById("social-sidebar-browser");
+ // setting isAppTab causes clicks on untargeted links to open new tabs
+ sbrowser.docShell.isAppTab = true;
+
this.updateSidebar();
},
// Whether the sidebar can be shown for this window.
get canShow() {
return Social.uiVisible && Social.provider.sidebarURL && !this.chromeless;
},
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1397,101 +1397,101 @@ var gBrowserInit = {
window.addEventListener("resize", function resizeHandler(event) {
if (event.target == window)
setUrlAndSearchBarWidthForConditionalForwardButton();
});
// Enable developer toolbar?
let devToolbarEnabled = gPrefService.getBoolPref("devtools.toolbar.enabled");
if (devToolbarEnabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_DevToolbar");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:DevToolbar");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
document.getElementById("Tools:DevToolbarFocus").removeAttribute("disabled");
// Show the toolbar if it was previously visible
if (gPrefService.getBoolPref("devtools.toolbar.visible")) {
DeveloperToolbar.show(false);
}
}
// Enable Inspector?
let enabled = gPrefService.getBoolPref("devtools.inspector.enabled");
if (enabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_Inspect");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:Inspect");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Debugger?
let enabled = gPrefService.getBoolPref("devtools.debugger.enabled");
if (enabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_Debugger");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:Debugger");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Remote Debugger?
let enabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
if (enabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_RemoteDebugger");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:RemoteDebugger");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Chrome Debugger?
let enabled = gPrefService.getBoolPref("devtools.chrome.enabled") &&
gPrefService.getBoolPref("devtools.debugger.chrome-enabled") &&
gPrefService.getBoolPref("devtools.debugger.remote-enabled");
if (enabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_ChromeDebugger");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:ChromeDebugger");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Error Console?
// XXX Temporarily always-enabled, see bug 601201
let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled");
if (consoleEnabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_ErrorConsole");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:ErrorConsole");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Scratchpad in the UI, if the preference allows this.
let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName);
if (scratchpadEnabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_Scratchpad");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:Scratchpad");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
// Enable Style Editor?
let styleEditorEnabled = gPrefService.getBoolPref(StyleEditor.prefEnabledName);
if (styleEditorEnabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_StyleEditor");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:StyleEditor");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
#ifdef MENUBAR_CAN_AUTOHIDE
// If the user (or the locale) hasn't enabled the top-level "Character
// Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
// hide it.
if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
Ci.nsIPrefLocalizedString).data)
document.getElementById("appmenu_charsetMenu").hidden = true;
#endif
// Enable Responsive UI?
let responsiveUIEnabled = gPrefService.getBoolPref("devtools.responsiveUI.enabled");
if (responsiveUIEnabled) {
- let broadcaster = document.getElementById("devtoolsMenuBroadcaster_ResponsiveUI");
- broadcaster.removeAttribute("disabled");
- broadcaster.removeAttribute("hidden");
+ let cmd = document.getElementById("Tools:ResponsiveUI");
+ cmd.removeAttribute("disabled");
+ cmd.removeAttribute("hidden");
}
let appMenuButton = document.getElementById("appmenu-button");
let appMenuPopup = document.getElementById("appmenu-popup");
if (appMenuButton && appMenuPopup) {
let appMenuOpening = null;
appMenuButton.addEventListener("mousedown", function(event) {
if (event.button == 0)
@@ -4676,25 +4676,19 @@ var TabsOnTop = {
}
var TabsInTitlebar = {
init: function () {
#ifdef CAN_DRAW_IN_TITLEBAR
this._readPref();
Services.prefs.addObserver(this._prefName, this, false);
- // Don't trust the initial value of the sizemode attribute; wait for the resize event.
+ // Don't trust the initial value of the sizemode attribute; wait for
+ // the resize event (handled in tabbrowser.xml).
this.allowedBy("sizemode", false);
- window.addEventListener("resize", function (event) {
- if (event.target != window)
- return;
- let sizemode = document.documentElement.getAttribute("sizemode");
- TabsInTitlebar.allowedBy("sizemode",
- sizemode == "maximized" || sizemode == "fullscreen");
- }, false);
this._initialized = true;
#endif
},
allowedBy: function (condition, allow) {
#ifdef CAN_DRAW_IN_TITLEBAR
if (allow) {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1065,35 +1065,35 @@
<tabbrowser id="content" disablehistory="true"
flex="1" contenttooltip="aHTMLTooltip"
tabcontainer="tabbrowser-tabs"
contentcontextmenu="contentAreaContextMenu"
autocompletepopup="PopupAutoComplete"
onclick="contentAreaClick(event, false);"/>
<statuspanel id="statusbar-display" inactive="true"/>
</vbox>
+ <splitter id="devtools-side-splitter" hidden="true"/>
+ <vbox id="devtools-sidebar-box" hidden="true"
+ style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
+ <toolbar id="devtools-sidebar-toolbar"
+ class="devtools-toolbar"
+ nowindowdrag="true"/>
+ <deck id="devtools-sidebar-deck" flex="1"/>
+ </vbox>
<splitter id="social-sidebar-splitter"
class="chromeclass-extrachrome"
observes="socialSidebarBroadcaster"/>
<vbox id="social-sidebar-box"
class="chromeclass-extrachrome"
observes="socialSidebarBroadcaster">
<browser id="social-sidebar-browser"
type="content"
flex="1"
style="min-width: 14em; width: 18em; max-width: 36em;"/>
</vbox>
- <splitter id="devtools-side-splitter" hidden="true"/>
- <vbox id="devtools-sidebar-box" hidden="true"
- style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
- <toolbar id="devtools-sidebar-toolbar"
- class="devtools-toolbar"
- nowindowdrag="true"/>
- <deck id="devtools-sidebar-deck" flex="1"/>
- </vbox>
<vbox id="browser-border-end" hidden="true" layer="true"/>
</hbox>
<hbox id="full-screen-warning-container" hidden="true" fadeout="true">
<hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
<vbox id="full-screen-warning-message" align="center">
<description id="full-screen-domain-text"/>
<description class="full-screen-description" value="&fullscreenExitHint.value;"/>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3087,23 +3087,29 @@
<body><![CDATA[
switch (aEvent.type) {
case "load":
this.updateVisibility();
break;
case "resize":
if (aEvent.target != window)
break;
+
+ let sizemode = document.documentElement.getAttribute("sizemode");
+ TabsInTitlebar.allowedBy("sizemode",
+ sizemode == "maximized" || sizemode == "fullscreen");
+
var width = this.mTabstrip.boxObject.width;
if (width != this.mTabstripWidth) {
this.adjustTabstrip();
this._fillTrailingGap();
this._handleTabSelect();
this.mTabstripWidth = width;
}
+
this.tabbrowser.updateWindowResizers();
break;
case "mouseout":
// If the "related target" (the node to which the pointer went) is not
// a child of the current document, the mouse just left the window.
let relatedTarget = aEvent.relatedTarget;
if (relatedTarget && relatedTarget.ownerDocument == document)
break;
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -256,16 +256,17 @@ endif
browser_tabDrop.js \
browser_lastAccessedTab.js \
browser_bug734076.js \
browser_social_toolbar.js \
browser_social_sidebar.js \
browser_social_mozSocial_API.js \
social_panel.html \
social_sidebar.html \
+ social_window.html \
social_worker.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
_BROWSER_FILES += \
browser_bug462289.js \
$(NULL)
else
--- a/browser/base/content/test/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/browser_social_mozSocial_API.js
@@ -5,83 +5,130 @@
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
function test() {
// XXX Bug 775779
if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
ok(true, "can't run social sidebar test in debug builds because they falsely report leaks");
return;
}
-
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "http://example.com",
sidebarURL: "http://example.com/browser/browser/base/content/test/social_sidebar.html",
workerURL: "http://example.com/browser/browser/base/content/test/social_worker.js",
iconURL: "chrome://branding/content/icon48.png"
};
- runSocialTestWithProvider(manifest, doTest);
+ runSocialTestWithProvider(manifest, function () {
+ runSocialTests(tests, undefined, undefined, function () {
+ SocialService.removeProvider(Social.provider.origin, finish);
+ });
+ });
}
-function doTest() {
- let iconsReady = false;
- let gotSidebarMessage = false;
+var tests = {
+ testStatusIcons: function(next) {
+ let iconsReady = false;
+ let gotSidebarMessage = false;
+
+ function checkNext() {
+ if (iconsReady && gotSidebarMessage)
+ triggerIconPanel();
+ }
+
+ function triggerIconPanel() {
+ let statusIcons = document.getElementById("social-status-iconbox");
+ ok(!statusIcons.firstChild.collapsed, "status icon is visible");
+ // Click the button to trigger its contentPanel
+ let panel = document.getElementById("social-notification-panel");
+ EventUtils.synthesizeMouseAtCenter(statusIcons.firstChild, {});
+ }
- function checkNext() {
- if (iconsReady && gotSidebarMessage)
- triggerIconPanel();
- }
-
- function triggerIconPanel() {
- let statusIcons = document.getElementById("social-status-iconbox");
- ok(!statusIcons.firstChild.collapsed, "status icon is visible");
- // Click the button to trigger its contentPanel
- let panel = document.getElementById("social-notification-panel");
- EventUtils.synthesizeMouseAtCenter(statusIcons.firstChild, {});
- }
+ let port = Social.provider.port;
+ ok(port, "provider has a port");
+ port.postMessage({topic: "test-init"});
+ Social.provider.port.onmessage = function (e) {
+ let topic = e.data.topic;
+ switch (topic) {
+ case "got-panel-message":
+ ok(true, "got panel message");
+ // Wait for the panel to close before ending the test
+ let panel = document.getElementById("social-notification-panel");
+ panel.addEventListener("popuphidden", function hiddenListener() {
+ panel.removeEventListener("popuphidden", hiddenListener);
+ next();
+ });
+ panel.hidePopup();
+ break;
+ case "got-sidebar-message":
+ // The sidebar message will always come first, since it loads by default
+ ok(true, "got sidebar message");
+ gotSidebarMessage = true;
+ checkNext();
+ break;
+ }
+ }
- let port = Social.provider.port;
- ok(port, "provider has a port");
- port.postMessage({topic: "test-init"});
- Social.provider.port.onmessage = function (e) {
- let topic = e.data.topic;
- switch (topic) {
- case "got-panel-message":
- ok(true, "got panel message");
- // Wait for the panel to close before ending the test
- let panel = document.getElementById("social-notification-panel");
- panel.addEventListener("popuphidden", function hiddenListener() {
- panel.removeEventListener("popuphidden", hiddenListener);
- SocialService.removeProvider(Social.provider.origin, finish);
+ // Our worker sets up ambient notification at the same time as it responds to
+ // the workerAPI initialization. If it's already initialized, we can
+ // immediately check the icons, otherwise wait for initialization by
+ // observing the topic sent out by the social service.
+ if (Social.provider.workerAPI.initialized) {
+ iconsReady = true;
+ checkNext();
+ } else {
+ Services.obs.addObserver(function obs() {
+ Services.obs.removeObserver(obs, "social:ambient-notification-changed");
+ // Let the other observers (like the one that updates the UI) run before
+ // checking the icons.
+ executeSoon(function () {
+ iconsReady = true;
+ checkNext();
});
- panel.hidePopup();
- break;
- case "got-sidebar-message":
- // The sidebar message will always come first, since it loads by default
- ok(true, "got sidebar message");
- info(topic);
- gotSidebarMessage = true;
- checkNext();
- break;
+ }, "social:ambient-notification-changed", false);
+ }
+ },
+
+ testServiceWindow: function(next) {
+ // our test provider was initialized in the test above, we just
+ // initiate our specific test now.
+ let port = Social.provider.port;
+ ok(port, "provider has a port");
+ port.postMessage({topic: "test-service-window"});
+ port.onmessage = function (e) {
+ let topic = e.data.topic;
+ switch (topic) {
+ case "got-service-window-message":
+ // The sidebar message will always come first, since it loads by default
+ ok(true, "got service window message");
+ port.postMessage({topic: "test-close-service-window"});
+ break;
+ case "got-service-window-closed-message":
+ ok(true, "got service window closed message");
+ next();
+ break;
+ }
+ }
+ },
+
+ testServiceWindowTwice: function(next) {
+ let port = Social.provider.port;
+ port.postMessage({topic: "test-service-window-twice"});
+ Social.provider.port.onmessage = function (e) {
+ let topic = e.data.topic;
+ switch (topic) {
+ case "test-service-window-twice-result":
+ is(e.data.result, "ok", "only one window should open when name is reused");
+ break;
+ case "got-service-window-message":
+ ok(true, "got service window message");
+ port.postMessage({topic: "test-close-service-window"});
+ break;
+ case "got-service-window-closed-message":
+ ok(true, "got service window closed message");
+ next();
+ break;
+ }
}
}
-
- // Our worker sets up ambient notification at the same time as it responds to
- // the workerAPI initialization. If it's already initialized, we can
- // immediately check the icons, otherwise wait for initialization by
- // observing the topic sent out by the social service.
- if (Social.provider.workerAPI.initialized) {
- iconsReady = true;
- checkNext();
- } else {
- Services.obs.addObserver(function obs() {
- Services.obs.removeObserver(obs, "social:ambient-notification-changed");
- // Let the other observers (like the one that updates the UI) run before
- // checking the icons.
- executeSoon(function () {
- iconsReady = true;
- checkNext();
- });
- }, "social:ambient-notification-changed", false);
- }
}
--- a/browser/base/content/test/browser_social_toolbar.js
+++ b/browser/base/content/test/browser_social_toolbar.js
@@ -9,17 +9,17 @@ function test() {
let manifest = { // normal provider
name: "provider 1",
origin: "https://example1.com",
workerURL: "https://example1.com/worker.js",
iconURL: "chrome://branding/content/icon48.png"
};
runSocialTestWithProvider(manifest, function () {
- runTests(tests, undefined, undefined, function () {
+ runSocialTests(tests, undefined, undefined, function () {
SocialService.removeProvider(Social.provider.origin, finish);
});
});
}
var tests = {
testProfileSet: function(next) {
let profile = {
@@ -69,47 +69,8 @@ var tests = {
ok(ambience.collapsed, "ambient icon is collapsed");
ambience = ambience.nextSibling;
}
next();
}
}
-function runTests(tests, cbPreTest, cbPostTest, cbFinish) {
- let testIter = Iterator(tests);
-
- if (cbPreTest === undefined) {
- cbPreTest = function(cb) {cb()};
- }
- if (cbPostTest === undefined) {
- cbPostTest = function(cb) {cb()};
- }
-
- function runNextTest() {
- let name, func;
- try {
- [name, func] = testIter.next();
- } catch (err if err instanceof StopIteration) {
- // out of items:
- (cbFinish || finish)();
- return;
- }
- // We run on a timeout as the frameworker also makes use of timeouts, so
- // this helps keep the debug messages sane.
- executeSoon(function() {
- function cleanupAndRunNextTest() {
- info("sub-test " + name + " complete");
- cbPostTest(runNextTest);
- }
- cbPreTest(function() {
- info("sub-test " + name + " starting");
- try {
- func.call(tests, cleanupAndRunNextTest);
- } catch (ex) {
- ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
- cleanupAndRunNextTest();
- }
- })
- });
- }
- runNextTest();
-}
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -113,8 +113,49 @@ function runSocialTestWithProvider(manif
} else {
Services.obs.addObserver(function obs() {
Services.obs.removeObserver(obs, "test-social-ui-ready");
saveOldProviderAndStartTestWith(provider);
}, "test-social-ui-ready", false);
}
});
}
+
+
+function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
+ let testIter = Iterator(tests);
+
+ if (cbPreTest === undefined) {
+ cbPreTest = function(cb) {cb()};
+ }
+ if (cbPostTest === undefined) {
+ cbPostTest = function(cb) {cb()};
+ }
+
+ function runNextTest() {
+ let name, func;
+ try {
+ [name, func] = testIter.next();
+ } catch (err if err instanceof StopIteration) {
+ // out of items:
+ (cbFinish || finish)();
+ return;
+ }
+ // We run on a timeout as the frameworker also makes use of timeouts, so
+ // this helps keep the debug messages sane.
+ executeSoon(function() {
+ function cleanupAndRunNextTest() {
+ info("sub-test " + name + " complete");
+ cbPostTest(runNextTest);
+ }
+ cbPreTest(function() {
+ info("sub-test " + name + " starting");
+ try {
+ func.call(tests, cleanupAndRunNextTest);
+ } catch (ex) {
+ ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
+ cleanupAndRunNextTest();
+ }
+ })
+ });
+ }
+ runNextTest();
+}
--- a/browser/base/content/test/social_sidebar.html
+++ b/browser/base/content/test/social_sidebar.html
@@ -1,14 +1,40 @@
<html>
<head>
<meta charset="utf-8">
<script>
+ var win;
function pingWorker() {
var port = navigator.mozSocial.getWorker().port;
+ port.onmessage = function(e) {
+ var topic = e.data.topic;
+ switch (topic) {
+ case "test-service-window":
+ win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
+ break;
+ case "test-service-window-twice":
+ win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
+ var win2 = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "");
+ var result;
+ if (win == win2)
+ result = "ok";
+ else
+ result = "not ok: " + win2 + " != " + win;
+ port.postMessage({topic: "test-service-window-twice-result", result: result});
+ break;
+ case "test-close-service-window":
+ win.addEventListener("unload", function watchClose() {
+ win.removeEventListener("unload", watchClose);
+ port.postMessage({topic: "service-window-closed-message", result: "ok"});
+ }, false)
+ win.close();
+ break;
+ }
+ }
port.postMessage({topic: "sidebar-message", result: "ok"});
}
</script>
</head>
<body onload="pingWorker();">
<p>This is a test social sidebar.</p>
</body>
</html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social_window.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script>
+ function pingWorker() {
+ var port = navigator.mozSocial.getWorker().port;
+ port.postMessage({topic: "service-window-message", result: "ok"});
+ }
+ </script>
+ </head>
+ <body onload="pingWorker();">
+ <p>This is a test social service window.</p>
+ </body>
+</html>
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social_worker.js
@@ -1,26 +1,45 @@
/* 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/. */
-let testPort;
+let testPort, sidebarPort;
onconnect = function(e) {
let port = e.ports[0];
port.onmessage = function onMessage(event) {
let topic = event.data.topic;
switch (topic) {
case "test-init":
testPort = port;
break;
case "sidebar-message":
+ sidebarPort = port;
if (testPort && event.data.result == "ok")
testPort.postMessage({topic:"got-sidebar-message"});
break;
+ case "service-window-message":
+ testPort.postMessage({topic:"got-service-window-message"});
+ break;
+ case "service-window-closed-message":
+ testPort.postMessage({topic:"got-service-window-closed-message"});
+ break;
+ case "test-service-window":
+ sidebarPort.postMessage({topic:"test-service-window"});
+ break;
+ case "test-service-window-twice":
+ sidebarPort.postMessage({topic:"test-service-window-twice"});
+ break;
+ case "test-service-window-twice-result":
+ testPort.postMessage({topic: "test-service-window-twice-result", result: event.data.result })
+ break;
+ case "test-close-service-window":
+ sidebarPort.postMessage({topic:"test-close-service-window"});
+ break;
case "panel-message":
if (testPort && event.data.result == "ok")
testPort.postMessage({topic:"got-panel-message"});
break;
case "social.initialize":
// This is the workerAPI port, respond and set up a notification icon.
port.postMessage({topic: "social.initialize-response"});
let profile = {
--- a/browser/devtools/tilt/test/Makefile.in
+++ b/browser/devtools/tilt/test/Makefile.in
@@ -5,21 +5,18 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = browser/devtools/tilt/test
include $(DEPTH)/config/autoconf.mk
-MOCHITEST_BROWSER_FILES = head.js
-
-# browser_tilt* disabled on Linux due to bug 759157
-ifneq (gtk2,$(MOZ_WIDGET_TOOLKIT))
-MOCHITEST_BROWSER_FILES += \
+MOCHITEST_BROWSER_FILES = \
+ head.js \
browser_tilt_01_lazy_getter.js \
browser_tilt_02_notifications-seq.js \
browser_tilt_02_notifications.js \
browser_tilt_03_tab_switch.js \
browser_tilt_04_initialization-key.js \
browser_tilt_04_initialization.js \
browser_tilt_05_destruction-esc.js \
browser_tilt_05_destruction-url.js \
@@ -55,11 +52,10 @@ MOCHITEST_BROWSER_FILES += \
browser_tilt_utils03.js \
browser_tilt_utils04.js \
browser_tilt_utils05.js \
browser_tilt_utils06.js \
browser_tilt_utils07.js \
browser_tilt_visualizer.js \
browser_tilt_zoom.js \
$(NULL)
-endif
include $(topsrcdir)/config/rules.mk
--- a/browser/devtools/webconsole/WebConsoleUtils.jsm
+++ b/browser/devtools/webconsole/WebConsoleUtils.jsm
@@ -533,17 +533,17 @@ var WebConsoleUtils = {
value = "";
presentable = {type: TYPES.GETTER, display: "Getter"};
}
else {
try {
value = aObject[propName];
presentable = this.presentableValueFor(value);
}
- catch (ex) {
+ catch (ex) {
continue;
}
}
let pair = {};
pair.name = propName;
pair.value = presentable.display;
pair.inspectable = false;
@@ -730,16 +730,18 @@ const STATE_DQUOTE = 3;
const OPEN_BODY = "{[(".split("");
const CLOSE_BODY = "}])".split("");
const OPEN_CLOSE_BODY = {
"{": "}",
"[": "]",
"(": ")",
};
+const MAX_COMPLETIONS = 256;
+
/**
* Analyses a given string to find the last statement that is interesting for
* later completion.
*
* @param string aStr
* A string to analyse.
*
* @returns object
@@ -890,19 +892,19 @@ function JSPropertyProvider(aScope, aInp
if (properties.length > 1) {
matchProp = properties.pop().trimLeft();
for (let i = 0; i < properties.length; i++) {
let prop = properties[i].trim();
if (!prop) {
return null;
}
- // If obj is undefined or null, then there is no chance to run completion
- // on it. Exit here.
- if (typeof obj === "undefined" || obj === null) {
+ // If obj is undefined or null (which is what "== null" does),
+ // then there is no chance to run completion on it. Exit here.
+ if (obj == null) {
return null;
}
// Check if prop is a getter function on obj. Functions can change other
// stuff so we can't execute them to get the next object. Stop here.
if (WCU.isNonNativeGetter(obj, prop)) {
return null;
}
@@ -913,34 +915,79 @@ function JSPropertyProvider(aScope, aInp
return null;
}
}
}
else {
matchProp = properties[0].trimLeft();
}
- // If obj is undefined or null, then there is no chance to run
- // completion on it. Exit here.
- if (typeof obj === "undefined" || obj === null) {
+ // If obj is undefined or null (which is what "== null" does),
+ // then there is no chance to run completion on it. Exit here.
+ if (obj == null) {
return null;
}
// Skip Iterators and Generators.
if (WCU.isIteratorOrGenerator(obj)) {
return null;
}
- let matches = [];
- for (let prop in obj) {
- if (prop.indexOf(matchProp) == 0) {
- matches.push(prop);
- }
- }
+ let matches = Object.keys(getMatchedProps(obj, matchProp));
return {
matchProp: matchProp,
matches: matches.sort(),
};
}
+/**
+ * Get all accessible properties on this object.
+ * Filter those properties by name.
+ * Take only a certain number of those.
+ *
+ * @param object obj
+ * Object whose properties we want to collect.
+ *
+ * @param string matchProp
+ * Filter for properties that match this one.
+ * Defaults to the empty string (which always matches).
+ *
+ * @return object
+ * Object whose keys are all accessible properties on the object.
+ */
+function getMatchedProps(aObj, aMatchProp = "")
+{
+ let c = MAX_COMPLETIONS;
+ let names = {}; // Using an Object to avoid duplicates.
+ let ownNames = Object.getOwnPropertyNames(aObj);
+ for (let i = 0; i < ownNames.length; i++) {
+ if (ownNames[i].indexOf(aMatchProp) == 0) {
+ if (names[ownNames[i]] != true) {
+ c--;
+ if (c < 0) {
+ return names;
+ }
+ names[ownNames[i]] = true;
+ }
+ }
+ }
+
+ // We need to recursively go up the prototype chain.
+ aObj = Object.getPrototypeOf(aObj);
+ if (aObj !== null) {
+ let parentScope = getMatchedProps(aObj, aMatchProp);
+ for (let name in parentScope) {
+ if (names[name] != true) {
+ c--;
+ if (c < 0) {
+ return names;
+ }
+ names[name] = true;
+ }
+ }
+ }
+ return names;
+}
+
+
return JSPropertyProvider;
})(WebConsoleUtils);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -30,43 +30,68 @@ function consoleOpened(aHud) {
ok(!popup.isOpen, "popup is not open");
popup._panel.addEventListener("popupshown", function onShown() {
popup._panel.removeEventListener("popupshown", onShown, false);
ok(popup.isOpen, "popup is open");
- is(popup.itemCount, 4, "popup.itemCount is correct");
+ // 4 values, and the following properties:
+ // __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__
+ // hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString
+ // toSource unwatch valueOf watch constructor.
+ is(popup.itemCount, 18, "popup.itemCount is correct");
- let sameItems = popup.getItems();
- is(sameItems.every(function(aItem, aIndex) {
- return aItem.label == "item" + aIndex;
- }), true, "getItems returns back the same items");
+ let sameItems = popup.getItems().map(function(e) {return e.label;});
+ ok(sameItems.every(function(prop, index) {
+ return [
+ "__defineGetter__",
+ "__defineSetter__",
+ "__lookupGetter__",
+ "__lookupSetter__",
+ "constructor",
+ "hasOwnProperty",
+ "isPrototypeOf",
+ "item0",
+ "item1",
+ "item2",
+ "item3",
+ "propertyIsEnumerable",
+ "toLocaleString",
+ "toSource",
+ "toString",
+ "unwatch",
+ "valueOf",
+ "watch",
+ ][index] === prop}), "getItems returns the items we expect");
is(popup.selectedIndex, -1, "no index is selected");
EventUtils.synthesizeKey("VK_DOWN", {});
-
+
let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
is(popup.selectedIndex, 0, "index 0 is selected");
- is(popup.selectedItem.label, "item0", "item0 is selected");
- is(completeNode.value, prefix + "item0", "completeNode.value holds item0");
+ is(popup.selectedItem.label, "__defineGetter__", "__defineGetter__ is selected");
+ is(completeNode.value, prefix + "__defineGetter__",
+ "completeNode.value holds __defineGetter__");
EventUtils.synthesizeKey("VK_DOWN", {});
is(popup.selectedIndex, 1, "index 1 is selected");
- is(popup.selectedItem.label, "item1", "item1 is selected");
- is(completeNode.value, prefix + "item1", "completeNode.value holds item1");
+ is(popup.selectedItem.label, "__defineSetter__", "__defineSetter__ is selected");
+ is(completeNode.value, prefix + "__defineSetter__",
+ "completeNode.value holds __defineSetter__");
EventUtils.synthesizeKey("VK_UP", {});
is(popup.selectedIndex, 0, "index 0 is selected");
- is(popup.selectedItem.label, "item0", "item0 is selected");
- is(completeNode.value, prefix + "item0", "completeNode.value holds item0");
+ is(popup.selectedItem.label, "__defineGetter__", "__defineGetter__ is selected");
+ is(completeNode.value, prefix + "__defineGetter__",
+ "completeNode.value holds __defineGetter__");
popup._panel.addEventListener("popuphidden", autocompletePopupHidden, false);
EventUtils.synthesizeKey("VK_TAB", {});
}, false);
jsterm.setInputValue("window.foobarBug585991");
EventUtils.synthesizeKey(".", {});
@@ -78,36 +103,37 @@ function autocompletePopupHidden()
let popup = jsterm.autocompletePopup;
let completeNode = jsterm.completeNode;
let inputNode = jsterm.inputNode;
popup._panel.removeEventListener("popuphidden", autocompletePopupHidden, false);
ok(!popup.isOpen, "popup is not open");
- is(inputNode.value, "window.foobarBug585991.item0",
+ is(inputNode.value, "window.foobarBug585991.__defineGetter__",
"completion was successful after VK_TAB");
ok(!completeNode.value, "completeNode is empty");
popup._panel.addEventListener("popupshown", function onShown() {
popup._panel.removeEventListener("popupshown", onShown, false);
ok(popup.isOpen, "popup is open");
- is(popup.itemCount, 4, "popup.itemCount is correct");
+ is(popup.itemCount, 18, "popup.itemCount is correct");
is(popup.selectedIndex, -1, "no index is selected");
EventUtils.synthesizeKey("VK_DOWN", {});
-
+
let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
is(popup.selectedIndex, 0, "index 0 is selected");
- is(popup.selectedItem.label, "item0", "item0 is selected");
- is(completeNode.value, prefix + "item0", "completeNode.value holds item0");
+ is(popup.selectedItem.label, "__defineGetter__", "__defineGetter__ is selected");
+ is(completeNode.value, prefix + "__defineGetter__",
+ "completeNode.value holds __defineGetter__");
popup._panel.addEventListener("popuphidden", function onHidden() {
popup._panel.removeEventListener("popuphidden", onHidden, false);
ok(!popup.isOpen, "popup is not open after VK_ESCAPE");
is(inputNode.value, "window.foobarBug585991.",
"completion was cancelled");
@@ -135,39 +161,41 @@ function testReturnKey()
let completeNode = jsterm.completeNode;
let inputNode = jsterm.inputNode;
popup._panel.addEventListener("popupshown", function onShown() {
popup._panel.removeEventListener("popupshown", onShown, false);
ok(popup.isOpen, "popup is open");
- is(popup.itemCount, 4, "popup.itemCount is correct");
-
+ is(popup.itemCount, 18, "popup.itemCount is correct");
+
is(popup.selectedIndex, -1, "no index is selected");
EventUtils.synthesizeKey("VK_DOWN", {});
let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
is(popup.selectedIndex, 0, "index 0 is selected");
- is(popup.selectedItem.label, "item0", "item0 is selected");
- is(completeNode.value, prefix + "item0", "completeNode.value holds item0");
+ is(popup.selectedItem.label, "__defineGetter__", "__defineGetter__ is selected");
+ is(completeNode.value, prefix + "__defineGetter__",
+ "completeNode.value holds __defineGetter__");
EventUtils.synthesizeKey("VK_DOWN", {});
is(popup.selectedIndex, 1, "index 1 is selected");
- is(popup.selectedItem.label, "item1", "item1 is selected");
- is(completeNode.value, prefix + "item1", "completeNode.value holds item1");
+ is(popup.selectedItem.label, "__defineSetter__", "__defineSetter__ is selected");
+ is(completeNode.value, prefix + "__defineSetter__",
+ "completeNode.value holds __defineSetter__");
popup._panel.addEventListener("popuphidden", function onHidden() {
popup._panel.removeEventListener("popuphidden", onHidden, false);
ok(!popup.isOpen, "popup is not open after VK_RETURN");
- is(inputNode.value, "window.foobarBug585991.item1",
+ is(inputNode.value, "window.foobarBug585991.__defineSetter__",
"completion was successful after VK_RETURN");
ok(!completeNode.value, "completeNode is empty");
executeSoon(finishTest);
}, false);
EventUtils.synthesizeKey("VK_RETURN", {});
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -29,18 +29,22 @@ function consoleOpened(aHud) {
ok(!popup.isOpen, "popup is not open");
popup._panel.addEventListener("popupshown", function onShown() {
popup._panel.removeEventListener("popupshown", onShown, false);
ok(popup.isOpen, "popup is open");
+ // |props| values, and the following properties:
+ // __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__
+ // constructor hasOwnProperty isPrototypeOf propertyIsEnumerable
+ // toLocaleString toSource toString unwatch valueOf watch.
let props = WCU.namesAndValuesOf(content.wrappedJSObject.document.body);
- is(popup.itemCount, props.length, "popup.itemCount is correct");
+ is(popup.itemCount, 14 + props.length, "popup.itemCount is correct");
popup._panel.addEventListener("popuphidden", autocompletePopupHidden, false);
EventUtils.synthesizeKey("VK_ESCAPE", {});
}, false);
jsterm.setInputValue("document.body");
EventUtils.synthesizeKey(".", {});
--- a/browser/devtools/webconsole/test/browser_webconsole_completion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_completion.js
@@ -45,16 +45,24 @@ function testCompletion(hud) {
jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
yield;
is(input.value, "document", "'docu' tab completion");
is(input.selectionStart, 8, "start selection is alright");
is(input.selectionEnd, 8, "end selection is alright");
is(jsterm.completeNode.value.replace(/ /g, ""), "", "'docu' completed");
+ // Test typing 'window.O' and press tab.
+ input.value = "window.O";
+ input.setSelectionRange(8, 8);
+ jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
+ yield;
+
+ is(input.value, "window.Object", "'window.O' tab completion");
+
// Test typing 'document.getElem'.
input.value = "document.getElem";
input.setSelectionRange(16, 16);
jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
yield;
is(input.value, "document.getElem", "'document.getElem' completion");
is(jsterm.completeNode.value, " entById", "'document.getElem' completion");
--- a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
@@ -449,66 +449,66 @@ addonDesc=Manipulate add-ons
# LOCALIZATION NOTE (addonListDesc) A very short description of the 'addon list'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible.
addonListDesc=List installed add-ons
# LOCALIZATION NOTE (addonListTypeDesc) A very short description of the
# 'addon list <type>' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
-addonListTypeDesc=Select an addon type
+addonListTypeDesc=Select an add-on type
# LOCALIZATION NOTE (addonListDictionaryHeading, addonListExtensionHeading,
# addonListLocaleHeading, addonListPluginHeading, addonListThemeHeading,
# addonListUnknownHeading) Used in the output of the 'addon list' command as the
# first line of output.
addonListDictionaryHeading=The following dictionaries are currently installed:
addonListExtensionHeading=The following extensions are currently installed:
addonListLocaleHeading=The following locales are currently installed:
addonListPluginHeading=The following plugins are currently installed:
addonListThemeHeading=The following themes are currently installed:
-addonListAllHeading=The following addons are currently installed:
-addonListUnknownHeading=The following addons of the selected type are currently installed:
+addonListAllHeading=The following add-ons are currently installed:
+addonListUnknownHeading=The following add-ons of the selected type are currently installed:
# LOCALIZATION NOTE (addonNameDesc) A very short description of the
-# name parameter of numerous addon commands. This string is designed to be shown
+# name parameter of numerous add-on commands. This string is designed to be shown
# in a menu alongside the command name, which is why it should be as short as
# possible.
addonNameDesc=The name of the add-on
# LOCALIZATION NOTE (addonNoneOfType) Used in the output of the 'addon list'
-# command when a search for addons of a particular type were not found.
-addonNoneOfType=There are no addons of that type installed.
+# command when a search for add-ons of a particular type were not found.
+addonNoneOfType=There are no add-ons of that type installed.
# LOCALIZATION NOTE (addonEnableDesc) A very short description of the
# 'addon enable <type>' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
addonEnableDesc=Enable the specified add-on
# LOCALIZATION NOTE (addonAlreadyEnabled) Used in the output of the
-# 'addon enable' command when an attempt is made to enable an addon is already
+# 'addon enable' command when an attempt is made to enable an add-on is already
# enabled.
addonAlreadyEnabled=%S is already enabled.
# LOCALIZATION NOTE (addonEnabled) Used in the output of the 'addon enable'
-# command when an addon is enabled.
+# command when an add-on is enabled.
addonEnabled=%S enabled.
# LOCALIZATION NOTE (addonDisableDesc) A very short description of the
# 'addon disable <type>' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
addonDisableDesc=Disable the specified add-on
# LOCALIZATION NOTE (addonAlreadyDisabled) Used in the output of the
-# 'addon disable' command when an attempt is made to disable an addon is already
+# 'addon disable' command when an attempt is made to disable an add-on is already
# disabled.
addonAlreadyDisabled=%S is already disabled.
# LOCALIZATION NOTE (addonDisabled) Used in the output of the 'addon disable'
-# command when an addon is disabled.
+# command when an add-on is disabled.
addonDisabled=%S disabled.
# LOCALIZATION NOTE (exportDesc) A very short description of the 'export'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible.
exportDesc=Export resources
# LOCALIZATION NOTE (exportHtmlDesc) A very short description of the 'export
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1263,16 +1263,17 @@ window[tabsontop="false"] richlistitem[t
#socialUserDisplayName,
#socialUserPortrait {
cursor: pointer;
}
#socialUserDisplayName {
-moz-appearance: none;
+ color: #fff;
border: none;
background-color: transparent;
margin-top: 0;
padding-top: 0;
font-size: 130%;
font-weight: bold;
}
@@ -3414,18 +3415,16 @@ stack[anonid=browserStack][responsivemod
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
}
/* === end of social toolbar button === */
/* === social toolbar provider menu === */
#social-statusarea-user {
- background-color: white;
- color: black;
cursor: default;
font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
font-size: 12px;
}
#social-statusarea-user-portrait {
width: 32px;
height: 32px;
@@ -3455,16 +3454,17 @@ stack[anonid=browserStack][responsivemod
max-height: 600px;
max-width: 400px;
}
#social-notification-panel .panel-arrowcontent {
margin: -4px 0 0 0;
padding: 0;
border-radius: 0px;
+ background-color: white;
}
#social-notification-panel .panel-arrow[side="top"] {
list-style-image: url("chrome://browser/skin/social/panelarrow-up.png");
margin-top: -4px;
margin-bottom: 3px;
height: 21px;
}
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -102,30 +102,31 @@ public class DoCommand {
String currentDir = "/";
String sErrorPrefix = "##AGENT-WARNING## ";
boolean bTraceOn = false;
String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp";
- private final String prgVersion = "SUTAgentAndroid Version 1.10";
+ private final String prgVersion = "SUTAgentAndroid Version 1.11";
public enum Command
{
RUN ("run"),
EXEC ("exec"),
EXECCWD ("execcwd"),
ENVRUN ("envrun"),
KILL ("kill"),
PS ("ps"),
DEVINFO ("info"),
OS ("os"),
ID ("id"),
UPTIME ("uptime"),
+ UPTIMEMILLIS ("uptimemillis"),
SETTIME ("settime"),
SYSTIME ("systime"),
SCREEN ("screen"),
ROTATION ("rotation"),
MEMORY ("memory"),
POWER ("power"),
PROCESS ("process"),
GETAPPROOT ("getapproot"),
@@ -416,16 +417,18 @@ public class DoCommand {
strReturn += SUTAgentAndroid.sUniqueID;
strReturn += "\n";
strReturn += GetOSInfo();
strReturn += "\n";
strReturn += GetSystemTime();
strReturn += "\n";
strReturn += GetUptime();
strReturn += "\n";
+ strReturn += GetUptimeMillis();
+ strReturn += "\n";
strReturn += GetScreenInfo();
strReturn += "\n";
strReturn += GetRotationInfo();
strReturn += "\n";
strReturn += GetMemoryInfo();
strReturn += "\n";
strReturn += GetPowerInfo();
strReturn += "\n";
@@ -459,16 +462,20 @@ public class DoCommand {
case SYSTIME:
strReturn = GetSystemTime();
break;
case UPTIME:
strReturn = GetUptime();
break;
+ case UPTIMEMILLIS:
+ strReturn = GetUptimeMillis();
+ break;
+
case MEMORY:
strReturn = GetMemoryInfo();
break;
case POWER:
strReturn += GetPowerInfo();
break;
@@ -2919,16 +2926,21 @@ private void CancelNotification()
nSecs = (int)(lHold / 1000L);
nMilliseconds = (int)(lHold % 1000);
sRet = "" + nDays + " days " + nHours + " hours " + nMinutes + " minutes " + nSecs + " seconds " + nMilliseconds + " ms";
}
return (sRet);
}
+ public String GetUptimeMillis()
+ {
+ return Long.toString(SystemClock.uptimeMillis());
+ }
+
public String NewKillProc(String sProcId, OutputStream out)
{
String sRet = "";
try
{
pProc = Runtime.getRuntime().exec("kill "+sProcId);
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
@@ -3766,16 +3778,17 @@ private void CancelNotification()
" key=value pairs (comma separated)\n" +
"kill [program name] - kill program no path\n" +
"killall - kill all processes started\n" +
"ps - list of running processes\n" +
"info - list of device info\n" +
" [os] - os version for device\n" +
" [id] - unique identifier for device\n" +
" [uptime] - uptime for device\n" +
+ " [uptimemillis] - uptime for device in milliseconds\n" +
" [systime] - current system time\n" +
" [screen] - width, height and bits per pixel for device\n" +
" [memory] - physical, free, available, storage memory\n" +
" for device\n" +
" [processes] - list of running processes see 'ps'\n" +
"deadman timeout - set the duration for the deadman timer\n" +
"alrt [on/off] - start or stop sysalert behavior\n" +
"disk [arg] - prints disk space info\n" +
--- a/build/pymake/tests/vpath-directive.mk
+++ b/build/pymake/tests/vpath-directive.mk
@@ -1,13 +1,10 @@
-ifdef __WIN32__
-VPSEP = ;
-else
-VPSEP = :
-endif
+# On Windows, MSYS make takes Unix paths but Pymake takes Windows paths
+VPSEP := $(if $(and $(__WIN32__),$(.PYMAKE)),;,:)
$(shell \
mkdir subd1 subd2 subd3; \
printf "reallybaddata" >subd1/foo.in; \
printf "gooddata" >subd2/foo.in; \
printf "baddata" >subd3/foo.in; \
touch subd1/foo.in2 subd2/foo.in2 subd3/foo.in2; \
)
--- a/build/virtualenv/packages.txt
+++ b/build/virtualenv/packages.txt
@@ -2,8 +2,10 @@ setup.py:other-licenses/simplejson-2.1.1
setup.py:testing/mozbase/manifestdestiny:develop
setup.py:testing/mozbase/mozinfo:develop
setup.py:testing/mozbase/mozinstall:develop
setup.py:testing/mozbase/mozlog:develop
setup.py:testing/mozbase/mozprocess:develop
setup.py:testing/mozbase/mozprofile:develop
setup.py:testing/mozbase/mozrunner:develop
setup.py:python/blessings:develop
+mozilla.pth:build
+mozilla.pth:config
--- a/build/virtualenv/populate_virtualenv.py
+++ b/build/virtualenv/populate_virtualenv.py
@@ -1,18 +1,20 @@
# 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/.
# This file contains code for populating the virtualenv environment for
# Mozilla's build system. It is typically called as part of configure.
+from __future__ import with_statement
import os.path
import subprocess
import sys
+import distutils.sysconfig
def populate_virtualenv(top_source_directory, manifest_filename):
"""Populate the virtualenv from the contents of a manifest.
The manifest file consists of colon-delimited fields. The first field
specifies the action. The remaining fields are arguments to that action.
The following actions are supported:
@@ -33,16 +35,21 @@ def populate_virtualenv(top_source_direc
fh.close()
for package in packages:
if package[0] == 'setup.py':
assert len(package) >= 2
call_setup(os.path.join(top_source_directory, package[1]),
package[2:])
+ if package[0].endswith('.pth'):
+ assert len(package) == 2
+
+ with open(os.path.join(distutils.sysconfig.get_python_lib(), package[0]), 'a') as f:
+ f.write("%s\n" % os.path.join(top_source_directory, package[1]))
def call_setup(directory, arguments):
"""Calls setup.py in a directory."""
setup = os.path.join(directory, 'setup.py')
program = [sys.executable, setup]
program.extend(arguments)
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -156,16 +156,17 @@ PYUNITS := \
unit-Expression.py \
unit-Preprocessor.py \
unit-nsinstall.py \
unit-printprereleasesuffix.py \
unit-JarMaker.py \
unit-buildlist.py \
unit-expandlibs.py \
unit-writemozinfo.py \
+ unit-mozunit.py \
$(NULL)
check-preqs = \
check-python-modules \
check-jar-mn \
check-makefiles \
$(NULL)
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -121,21 +121,23 @@ class Preprocessor:
if self.checkLineNumbers:
self.writtenLines += 1
ln = self.context['LINE']
if self.writtenLines != ln:
self.out.write('//@line %(line)d "%(file)s"%(le)s'%{'line': ln,
'file': self.context['FILE'],
'le': self.LE})
self.writtenLines = ln
- aLine = self.applyFilters(aLine)
+ filteredLine = self.applyFilters(aLine)
+ if filteredLine != aLine:
+ self.actionLevel = 2
# ensure our line ending. Only need to handle \n, as we're reading
# with universal line ending support, at least for files.
- aLine = re.sub('\n', self.LE, aLine)
- self.out.write(aLine)
+ filteredLine = re.sub('\n', self.LE, filteredLine)
+ self.out.write(filteredLine)
def handleCommandLine(self, args, defaultToStdin = False):
"""
Parse a commandline into this parser.
Uses OptionParser internally, no args mean sys.argv[1:].
"""
p = self.getCommandLineParser()
(options, args) = p.parse_args(args=args)
--- a/config/mozunit.py
+++ b/config/mozunit.py
@@ -1,25 +1,28 @@
# 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 unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
+import unittest
import inspect
+from StringIO import StringIO
+import os
'''Helper to make python unit tests report the way that the Mozilla
unit test infrastructure expects tests to report.
Usage:
import unittest
-from mozunit import MozTestRunner
+import mozunit
if __name__ == '__main__':
- unittest.main(testRunner=MozTestRunner())
+ mozunit.main()
'''
class _MozTestResult(_TestResult):
def __init__(self, stream, descriptions):
_TestResult.__init__(self)
self.stream = stream
self.descriptions = descriptions
@@ -63,8 +66,74 @@ class _MozTestResult(_TestResult):
class MozTestRunner(_TestRunner):
def _makeResult(self):
return _MozTestResult(self.stream, self.descriptions)
def run(self, test):
result = self._makeResult()
test(result)
result.printErrorList()
return result
+
+class MockedFile(StringIO):
+ def __init__(self, context, filename, content = ''):
+ self.context = context
+ self.name = filename
+ StringIO.__init__(self, content)
+
+ def close(self):
+ self.context.files[self.name] = self.getvalue()
+ StringIO.close(self)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+class MockedOpen(object):
+ '''
+ Context manager diverting the open builtin such that opening files
+ can open "virtual" file instances given when creating a MockedOpen.
+
+ with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
+ f = open('foo', 'r')
+
+ will thus open the virtual file instance for the file 'foo' to f.
+
+ MockedOpen also masks writes, so that creating or replacing files
+ doesn't touch the file system, while subsequently opening the file
+ will return the recorded content.
+
+ with MockedOpen():
+ f = open('foo', 'w')
+ f.write('foo')
+ self.assertRaises(Exception,f.open('foo', 'r'))
+ '''
+ def __init__(self, files = {}):
+ self.files = {}
+ for name, content in files.iteritems():
+ self.files[os.path.abspath(name)] = content
+
+ def __call__(self, name, mode = 'r'):
+ absname = os.path.abspath(name)
+ if 'w' in mode:
+ file = MockedFile(self, absname)
+ elif absname in self.files:
+ file = MockedFile(self, absname, self.files[absname])
+ elif 'a' in mode:
+ file = MockedFile(self, absname, self.open(name, 'r').read())
+ else:
+ file = self.open(name, mode)
+ if 'a' in mode:
+ file.seek(0, os.SEEK_END)
+ return file
+
+ def __enter__(self):
+ import __builtin__
+ self.open = __builtin__.open
+ __builtin__.open = self
+
+ def __exit__(self, type, value, traceback):
+ import __builtin__
+ __builtin__.open = self.open
+
+def main(*args):
+ unittest.main(testRunner=MozTestRunner(),*args)
--- a/config/tests/unit-Expression.py
+++ b/config/tests/unit-Expression.py
@@ -1,13 +1,13 @@
import unittest
import sys
import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from Expression import Expression, Context
class TestContext(unittest.TestCase):
"""
Unit tests for the Context class
"""
@@ -55,9 +55,9 @@ class TestExpression(unittest.TestCase):
""" Test for the == operator"""
self.assert_(Expression('FAIL == PASS').evaluate(self.c))
def test_notequals(self):
""" Test for the != operator"""
self.assert_(Expression('FAIL != 1').evaluate(self.c))
if __name__ == '__main__':
- unittest.main()
+ mozunit.main()
--- a/config/tests/unit-JarMaker.py
+++ b/config/tests/unit-JarMaker.py
@@ -1,18 +1,16 @@
import unittest
import os, sys, os.path, time, inspect
from filecmp import dircmp
from tempfile import mkdtemp
from shutil import rmtree, copy2
from zipfile import ZipFile
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-
-from mozunit import MozTestRunner
+import mozunit
from JarMaker import JarMaker
if sys.platform == "win32":
import ctypes
from ctypes import POINTER, WinError
DWORD = ctypes.c_ulong
LPDWORD = POINTER(DWORD)
HANDLE = ctypes.c_void_p
@@ -275,9 +273,9 @@ class TestJarMaker(unittest.TestCase):
open(os.path.join(ldir, relpath), 'w').write(relpath+" content\n")
# call JarMaker
difference = self._jar_and_compare(jars,
(_mangle,),
sourcedirs = [])
self.assertTrue(not difference, difference)
if __name__ == '__main__':
- unittest.main(testRunner=MozTestRunner())
+ mozunit.main()
--- a/config/tests/unit-LineEndings.py
+++ b/config/tests/unit-LineEndings.py
@@ -1,15 +1,15 @@
import unittest
from StringIO import StringIO
import os
import sys
import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from Preprocessor import Preprocessor
class TestLineEndings(unittest.TestCase):
"""
Unit tests for the Context class
"""
@@ -38,9 +38,9 @@ class TestLineEndings(unittest.TestCase)
self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
def testWindows(self):
self.createFile(['\x0D\x0A']*3)
self.pp.do_include(self.tempnam)
self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
if __name__ == '__main__':
- unittest.main()
+ mozunit.main()
--- a/config/tests/unit-Preprocessor.py
+++ b/config/tests/unit-Preprocessor.py
@@ -1,50 +1,23 @@
from __future__ import with_statement
import unittest
from StringIO import StringIO
import os
import sys
import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+from mozunit import main, MockedOpen
from Preprocessor import Preprocessor
-class NamedIO(StringIO):
- def __init__(self, name, content):
- self.name = name
- StringIO.__init__(self, content)
-
-class MockedOpen(object):
- """
- Context manager diverting the open builtin such that opening files
- can open NamedIO instances given when creating a MockedOpen.
-
- with MockedOpen(NamedIO('foo', 'foo'), NamedIO('bar', 'bar')):
- f = open('foo', 'r')
-
- will thus assign the NamedIO instance for the file 'foo' to f.
- """
- def __init__(self, *files):
- self.files = {}
- for f in files:
- self.files[os.path.abspath(f.name)] = f
- def __call__(self, name, args):
- absname = os.path.abspath(name)
- if absname in self.files:
- return self.files[absname]
- return self.open(name, args)
- def __enter__(self):
- import __builtin__
- self.open = __builtin__.open
- __builtin__.open = self
- def __exit__(self, type, value, traceback):
- import __builtin__
- __builtin__.open = self.open
+def NamedIO(name, content):
+ with open(name, 'w') as f:
+ f.write(content)
+ return name
class TestPreprocessor(unittest.TestCase):
"""
Unit tests for the Context class
"""
def setUp(self):
self.pp = Preprocessor()
@@ -534,23 +507,23 @@ octal value is not equal
try:
self.pp.do_include(f)
except Preprocessor.Error, exception:
self.assertEqual(exception.key, 'UNDEFINED_VAR')
else:
self.fail("Expected a Preprocessor.Error")
def test_include(self):
- with MockedOpen(NamedIO("foo/test", """#define foo foobarbaz
+ with MockedOpen({"foo/test": """#define foo foobarbaz
#include @inc@
@bar@
-"""),
- NamedIO("bar", """#define bar barfoobaz
+""",
+ "bar": """#define bar barfoobaz
@foo@
-""")):
+"""}):
f = NamedIO("include.in", """#filter substitution
#define inc ../bar
#include foo/test""")
self.pp.do_include(f)
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
barfoobaz
""")
@@ -570,26 +543,26 @@ barfoobaz
try:
self.pp.do_include(f)
except Preprocessor.Error, exception:
self.assertEqual(exception.key, 'UNDEFINED_VAR')
else:
self.fail("Expected a Preprocessor.Error")
def test_include_literal_at(self):
- with MockedOpen(NamedIO("@foo@", "#define foo foobarbaz")):
+ with MockedOpen({"@foo@": "#define foo foobarbaz"}):
f = NamedIO("include_literal_at.in", """#include @foo@
#filter substitution
@foo@
""")
self.pp.do_include(f)
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
""")
def test_command_line_literal_at(self):
- with MockedOpen(NamedIO("@foo@.in", """@foo@
-""")):
+ with MockedOpen({"@foo@.in": """@foo@
+"""}):
self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
""")
if __name__ == '__main__':
- unittest.main()
+ main()
--- a/config/tests/unit-buildlist.py
+++ b/config/tests/unit-buildlist.py
@@ -1,14 +1,14 @@
import unittest
import os, sys, os.path, time
from tempfile import mkdtemp
from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from buildlist import addEntriesToListFile
class TestBuildList(unittest.TestCase):
"""
Unit tests for buildlist.py
"""
def setUp(self):
@@ -72,9 +72,9 @@ class TestBuildList(unittest.TestCase):
only one entry being added."""
testfile = os.path.join(self.tmpdir, "test.list")
addEntriesToListFile(testfile, ["a","b","a","a","b"])
self.assertFileContains(testfile, ["a","b"])
addEntriesToListFile(testfile, ["c","a","c","b","c"])
self.assertFileContains(testfile, ["a","b","c"])
if __name__ == '__main__':
- unittest.main()
+ mozunit.main()
--- a/config/tests/unit-expandlibs.py
+++ b/config/tests/unit-expandlibs.py
@@ -1,18 +1,17 @@
from __future__ import with_statement
import subprocess
import unittest
import sys
import os
import imp
from tempfile import mkdtemp
from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from mozunit import MozTestRunner
+import mozunit
from UserString import UserString
# Create a controlled configuration for use by expandlibs
config_win = {
'AR_EXTRACT': '',
'DLL_PREFIX': '',
'LIB_PREFIX': '',
'OBJ_SUFFIX': '.obj',
@@ -380,9 +379,9 @@ class TestSymbolOrder(unittest.TestCase)
config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
subprocess.Popen = subprocess_popen
if __name__ == '__main__':
- unittest.main(testRunner=MozTestRunner())
+ mozunit.main()
new file mode 100644
--- /dev/null
+++ b/config/tests/unit-mozunit.py
@@ -0,0 +1,75 @@
+# 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 with_statement
+import sys
+import os
+from mozunit import main, MockedOpen
+import unittest
+from tempfile import mkstemp
+
+class TestMozUnit(unittest.TestCase):
+ def test_mocked_open(self):
+ # Create a temporary file on the file system.
+ (fd, path) = mkstemp()
+ with os.fdopen(fd, 'w') as file:
+ file.write('foobar');
+
+ with MockedOpen({'file1': 'content1',
+ 'file2': 'content2'}):
+ # Check the contents of the files given at MockedOpen creation.
+ self.assertEqual(open('file1', 'r').read(), 'content1')
+ self.assertEqual(open('file2', 'r').read(), 'content2')
+
+ # Check that overwriting these files alters their content.
+ with open('file1', 'w') as file:
+ file.write('foo')
+ self.assertEqual(open('file1', 'r').read(), 'foo')
+
+ # ... but not until the file is closed.
+ file = open('file2', 'w')
+ file.write('bar')
+ self.assertEqual(open('file2', 'r').read(), 'content2')
+ file.close()
+ self.assertEqual(open('file2', 'r').read(), 'bar')
+
+ # Check that appending to a file does append
+ with open('file1', 'a') as file:
+ file.write('bar')
+ self.assertEqual(open('file1', 'r').read(), 'foobar')
+
+ # Opening a non-existing file ought to fail.
+ self.assertRaises(IOError, open, 'file3', 'r')
+
+ # Check that writing a new file does create the file.
+ with open('file3', 'w') as file:
+ file.write('baz')
+ self.assertEqual(open('file3', 'r').read(), 'baz')
+
+ # Check the content of the file created outside MockedOpen.
+ self.assertEqual(open(path, 'r').read(), 'foobar')
+
+ # Check that overwriting a file existing on the file system
+ # does modify its content.
+ with open(path, 'w') as file:
+ file.write('bazqux')
+ self.assertEqual(open(path, 'r').read(), 'bazqux')
+
+ with MockedOpen():
+ # Check that appending to a file existing on the file system
+ # does modify its content.
+ with open(path, 'a') as file:
+ file.write('bazqux')
+ self.assertEqual(open(path, 'r').read(), 'foobarbazqux')
+
+ # Check that the file was not actually modified on the file system.
+ self.assertEqual(open(path, 'r').read(), 'foobar')
+ os.remove(path)
+
+ # Check that the file created inside MockedOpen wasn't actually
+ # created.
+ self.assertRaises(IOError, open, 'file3', 'r')
+
+if __name__ == "__main__":
+ main()
--- a/config/tests/unit-nsinstall.py
+++ b/config/tests/unit-nsinstall.py
@@ -1,14 +1,14 @@
import unittest
import os, sys, os.path, time
from tempfile import mkdtemp
from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from mozprocess import processhandler
from nsinstall import nsinstall
import nsinstall as nsinstall_module
NSINSTALL_PATH = nsinstall_module.__file__
# Run the non-ASCII tests on (a) Windows, or (b) any platform with
# sys.stdin.encoding set to UTF-8
@@ -165,9 +165,9 @@ class TestNsinstall(unittest.TestCase):
self.assertEqual(rv, 0)
destfile = os.path.join(testdir, filename)
self.assert_(os.path.isfile(destfile))
#TODO: implement -R, -l, -L and test them!
if __name__ == '__main__':
- unittest.main()
+ mozunit.main()
--- a/config/tests/unit-printprereleasesuffix.py
+++ b/config/tests/unit-printprereleasesuffix.py
@@ -1,13 +1,13 @@
import unittest
import sys
import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from printprereleasesuffix import get_prerelease_suffix
class TestGetPreReleaseSuffix(unittest.TestCase):
"""
Unit tests for the get_prerelease_suffix function
"""
@@ -72,9 +72,9 @@ class TestGetPreReleaseSuffix(unittest.T
self.assertEqual(self.c, '')
def test_plus(self):
"""test 1.2+ version string """
self.c = get_prerelease_suffix('1.2+')
self.assertEqual(self.c, '')
if __name__ == '__main__':
- unittest.main()
+ mozunit.main()
--- a/config/tests/unit-writemozinfo.py
+++ b/config/tests/unit-writemozinfo.py
@@ -1,15 +1,14 @@
#!/usr/bin/env python
from __future__ import with_statement
import unittest
import os, sys, time, tempfile
from StringIO import StringIO
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
from writemozinfo import build_dict, write_json, JsonValue, jsonify
class TestBuildDict(unittest.TestCase):
def testMissing(self):
"""
Test that missing required values raises.
"""
@@ -234,10 +233,9 @@ class TestWriteJson(unittest.TestCase):
'MOZ_WIDGET_TOOLKIT':'windows'})
d = parse_json(s.getvalue())
self.assertEqual('win', d['os'])
self.assertEqual('x86', d['processor'])
self.assertEqual('windows', d['toolkit'])
self.assertEqual(32, d['bits'])
if __name__ == '__main__':
- unittest.main()
-
+ mozunit.main()
--- a/configure.in
+++ b/configure.in
@@ -745,16 +745,19 @@ if test -n "$_WIN32_MSVC"; then
SKIP_COMPILER_CHECKS=1
SKIP_LIBRARY_CHECKS=1
# Since we're skipping compiler and library checks, hard-code
# some facts here.
AC_DEFINE(HAVE_IO_H)
AC_DEFINE(HAVE_SETBUF)
AC_DEFINE(HAVE_ISATTY)
+ if test $_MSC_VER -ge 1600; then
+ AC_DEFINE(HAVE_NULLPTR)
+ fi
fi
fi # COMPILE_ENVIRONMENT
AC_SUBST(MIDL_FLAGS)
AC_SUBST(_MSC_VER)
AC_SUBST(GNU_AS)
@@ -5585,17 +5588,17 @@ if test "$MOZ_GSTREAMER"; then
# introduced
GST_VERSION=0.10.33
PKG_CHECK_MODULES(GSTREAMER,
gstreamer-$GST_API_VERSION >= $GST_VERSION
gstreamer-app-$GST_API_VERSION
gstreamer-plugins-base-$GST_API_VERSION)
if test -n "$GSTREAMER_LIBS"; then
_SAVE_LDFLAGS=$LDFLAGS
- LDFLAGS="$LDFLAGS -lgstvideo-$GST_API_VERSION"
+ LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
if test -n "$_HAVE_LIBGSTVIDEO" ; then
GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
else
AC_MSG_ERROR([gstreamer video backend requires libgstvideo])
fi
LDFLAGS=$_SAVE_LDFLAGS
else
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -36,16 +36,17 @@
#include "nsIScriptChannel.h"
#include "nsIBlocklistService.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIAppShell.h"
#include "nsPluginError.h"
// Util headers
+#include "prenv.h"
#include "prlog.h"
#include "nsAutoPtr.h"
#include "nsCURILoader.h"
#include "nsContentPolicyUtils.h"
#include "nsContentUtils.h"
#include "nsDocShellCID.h"
#include "nsGkAtoms.h"
@@ -1215,19 +1216,26 @@ nsObjectLoadingContent::ObjectState() co
state |= NS_EVENT_STATE_HANDLER_DISABLED;
break;
case ePluginBlocklisted:
state |= NS_EVENT_STATE_HANDLER_BLOCKED;
break;
case ePluginCrashed:
state |= NS_EVENT_STATE_HANDLER_CRASHED;
break;
- case ePluginUnsupported:
- state |= NS_EVENT_STATE_TYPE_UNSUPPORTED;
+ case ePluginUnsupported: {
+ // Check to see if plugins are blocked on this platform.
+ char* pluginsBlocked = PR_GetEnv("MOZ_PLUGINS_BLOCKED");
+ if (pluginsBlocked && pluginsBlocked[0] == '1') {
+ state |= NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM;
+ } else {
+ state |= NS_EVENT_STATE_TYPE_UNSUPPORTED;
+ }
break;
+ }
case ePluginOutdated:
case ePluginOtherState:
// Do nothing, but avoid a compile warning
break;
}
return state;
};
NS_NOTREACHED("unknown type?");
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1452,17 +1452,17 @@ nsXMLHttpRequest::GetAllResponseHeaders(
nsCAutoString value;
if (NS_SUCCEEDED(mChannel->GetContentType(value))) {
aResponseHeaders.AppendLiteral("Content-Type: ");
AppendASCIItoUTF16(value, aResponseHeaders);
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) {
aResponseHeaders.AppendLiteral(";charset=");
AppendASCIItoUTF16(value, aResponseHeaders);
}
- aResponseHeaders.Append('\n');
+ aResponseHeaders.AppendLiteral("\r\n");
}
}
NS_IMETHODIMP
nsXMLHttpRequest::GetResponseHeader(const nsACString& aHeader,
nsACString& aResult)
{
ErrorResult rv;
@@ -3976,17 +3976,17 @@ nsHeaderVisitor::VisitHeader(const nsACS
if (!chrome &&
(header.LowerCaseEqualsASCII("set-cookie") ||
header.LowerCaseEqualsASCII("set-cookie2"))) {
NS_WARNING("blocked access to response header");
} else {
mHeaders.Append(header);
mHeaders.Append(": ");
mHeaders.Append(value);
- mHeaders.Append('\n');
+ mHeaders.Append("\r\n");
}
return NS_OK;
}
// DOM event class to handle progress notifications
nsXMLHttpProgressEvent::nsXMLHttpProgressEvent(nsIDOMProgressEvent* aInner,
PRUint64 aCurrentProgress,
PRUint64 aMaxProgress,
--- a/content/base/test/test_XHR.html
+++ b/content/base/test/test_XHR.html
@@ -43,17 +43,17 @@ for (i = 0; i < passFiles.length; ++i) {
is(xhr.getResponseHeader("Content-Type"), null, "should be null");
is(xhr.getAllResponseHeaders(), "", "should be empty string");
is(xhr.responseType, "", "wrong initial responseType");
xhr.open(passFiles[i][1], passFiles[i][0], false);
xhr.send(null);
is(xhr.status, passFiles[i][2], "wrong status");
is(xhr.getResponseHeader("Content-Type"), passFiles[i][3], "wrong content type");
var headers = xhr.getAllResponseHeaders();
- ok(/(?:^|\n)Content-Type:\s*([^\n]*)\n/i.test(headers) &&
+ ok(/(?:^|\n)Content-Type:\s*([^\r\n]*)\r\n/i.test(headers) &&
RegExp.$1 === passFiles[i][3], "wrong response headers");
if (xhr.responseXML) {
is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement),
passFiles[i][4] || "<res>hello</res>", "wrong responseXML");
is(xhr.response, passFiles[i][4] || "<res>hello</res>\n", "wrong response");
}
else {
is(xhr.responseText, passFiles[i][4] || "hello pass\n", "wrong responseText");
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -151,16 +151,17 @@ WebGLContext::WebGLContext()
mAllowRestore = true;
mContextLossTimerRunning = false;
mDrawSinceContextLossTimerSet = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
mContextStatus = ContextStable;
mContextLostErrorSet = false;
mAlreadyGeneratedWarnings = 0;
+ mAlreadyWarnedAboutFakeVertexAttrib0 = false;
}
WebGLContext::~WebGLContext()
{
DestroyResourcesAndContext();
WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
TerminateContextLossTimer();
mContextRestorer = nsnull;
@@ -928,19 +929,27 @@ WebGLContext::GetExtension(const nsAStri
ext = OES_texture_float;
}
else if (aName.Equals(NS_LITERAL_STRING("OES_standard_derivatives"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(OES_standard_derivatives))
ext = OES_standard_derivatives;
}
+ else if (aName.Equals(NS_LITERAL_STRING("EXT_texture_filter_anisotropic"),
+ nsCaseInsensitiveStringComparator()))
+ {
+ if (IsExtensionSupported(EXT_texture_filter_anisotropic))
+ ext = EXT_texture_filter_anisotropic;
+ }
else if (aName.Equals(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"),
nsCaseInsensitiveStringComparator()))
{
+ GenerateWarning("MOZ_EXT_texture_filter_anisotropic has been renamed to EXT_texture_filter_anisotropic. "
+ "Support for the MOZ_-prefixed string will be removed very soon.");
if (IsExtensionSupported(EXT_texture_filter_anisotropic))
ext = EXT_texture_filter_anisotropic;
}
else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(WEBGL_lose_context))
ext = WEBGL_lose_context;
@@ -1533,18 +1542,20 @@ WebGLContext::GetSupportedExtensions(Nul
}
nsTArray<nsString>& arr = retval.SetValue();
if (IsExtensionSupported(OES_texture_float))
arr.AppendElement(NS_LITERAL_STRING("OES_texture_float"));
if (IsExtensionSupported(OES_standard_derivatives))
arr.AppendElement(NS_LITERAL_STRING("OES_standard_derivatives"));
- if (IsExtensionSupported(EXT_texture_filter_anisotropic))
+ if (IsExtensionSupported(EXT_texture_filter_anisotropic)) {
+ arr.AppendElement(NS_LITERAL_STRING("EXT_texture_filter_anisotropic"));
arr.AppendElement(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"));
+ }
if (IsExtensionSupported(WEBGL_lose_context))
arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"));
if (IsExtensionSupported(WEBGL_compressed_texture_s3tc))
arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"));
}
NS_IMETHODIMP
WebGLContext::IsContextLost(WebGLboolean *retval)
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1354,16 +1354,17 @@ protected:
nsCOMPtr<nsITimer> mContextRestorer;
bool mAllowRestore;
bool mContextLossTimerRunning;
bool mDrawSinceContextLossTimerSet;
ContextStatus mContextStatus;
bool mContextLostErrorSet;
int mAlreadyGeneratedWarnings;
+ bool mAlreadyWarnedAboutFakeVertexAttrib0;
bool ShouldGenerateWarnings() const {
return mAlreadyGeneratedWarnings < 32;
}
#ifdef XP_MACOSX
// see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
// Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -437,16 +437,19 @@ GLenum WebGLContext::CheckedBufferData(G
return LOCAL_GL_NO_ERROR;
}
}
NS_IMETHODIMP
WebGLContext::BufferData(WebGLenum target, const JS::Value& data, GLenum usage,
JSContext* cx)
{
+ if (!IsContextStable())
+ return NS_OK;
+
if (data.isNull()) {
BufferData(target, static_cast<ArrayBuffer*>(nsnull), usage);
return NS_OK;
}
if (data.isObject()) {
JSObject& dataObj = data.toObject();
if (JS_IsArrayBufferObject(&dataObj, cx)) {
@@ -1520,18 +1523,27 @@ WebGLContext::WhatDoesVertexAttrib0Need(
bool
WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount)
{
int whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (whatDoesAttrib0Need == VertexAttrib0Status::Default)
return true;
+ if (!mAlreadyWarnedAboutFakeVertexAttrib0) {
+ GenerateWarning("Drawing without vertex attrib 0 array enabled forces the browser "
+ "to do expensive emulation work when running on desktop OpenGL "
+ "platforms, for example on Mac. It is preferable to always draw "
+ "with vertex attrib 0 array enabled, by using bindAttribLocation "
+ "to bind some always-used attribute to location 0.");
+ mAlreadyWarnedAboutFakeVertexAttrib0 = true;
+ }
+
CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
-
+
if (!checked_dataSize.isValid()) {
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
"with %d vertices. Try reducing the number of vertices.", vertexCount);
return false;
}
WebGLuint dataSize = checked_dataSize.value();
@@ -5017,19 +5029,23 @@ WebGLContext::CompileShader(WebGLShader
shader->mUniforms.AppendElement(WebGLMappedIdentifier(
nsDependentCString(uniform_name),
nsDependentCString(mapped_name)));
}
// we always query uniform info, regardless of useShaderSourceTranslation,
// as we need it to validate uniform setter calls, and it doesn't rely on
// shader translation.
+ char mappedNameLength = strlen(mapped_name);
+ char mappedNameLastChar = mappedNameLength > 1
+ ? mapped_name[mappedNameLength - 1]
+ : 0;
shader->mUniformInfos.AppendElement(WebGLUniformInfo(
size,
- length > 1 && mapped_name[length - 1] == ']',
+ mappedNameLastChar == ']',
type));
}
if (useShaderSourceTranslation) {
for (int i = 0; i < num_attributes; i++) {
int length, size;
ShDataType type;
--- a/content/events/public/nsEventStates.h
+++ b/content/events/public/nsEventStates.h
@@ -241,16 +241,18 @@ private:
// Content is in the suboptimal region.
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
// Content is in the sub-suboptimal region.
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(39)
// Handler for click to play plugin (vulnerable w/update)
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(40)
// Handler for click to play plugin (vulnerable w/no update)
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(41)
+// Platform does not support plugin content (some mobile platforms)
+#define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(42)
/**
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
*/
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -31,18 +31,16 @@ CPPSRCS = \
nsDOMUIEvent.cpp \
nsDOMKeyboardEvent.cpp \
nsDOMTextEvent.cpp \
nsDOMMouseEvent.cpp \
nsDOMMouseScrollEvent.cpp \
nsDOMDragEvent.cpp \
nsDOMMutationEvent.cpp \
nsDOMPopupBlockedEvent.cpp \
- nsDOMDeviceLightEvent.cpp \
- nsDOMDeviceOrientationEvent.cpp \
nsDOMDeviceMotionEvent.cpp \
nsDOMBeforeUnloadEvent.cpp \
nsDOMXULCommandEvent.cpp \
nsDOMCommandEvent.cpp \
nsDOMMessageEvent.cpp \
nsPaintRequest.cpp \
nsPrivateTextRange.cpp \
nsXMLEventsManager.cpp \
@@ -60,17 +58,16 @@ CPPSRCS = \
nsDOMMozTouchEvent.cpp \
nsDOMEventTargetHelper.cpp \
nsDOMScrollAreaEvent.cpp \
nsDOMTransitionEvent.cpp \
nsDOMAnimationEvent.cpp \
nsDOMSettingsEvent.cpp \
nsDOMTouchEvent.cpp \
nsDOMCompositionEvent.cpp \
- nsDOMApplicationEvent.cpp \
$(NULL)
ifdef MOZ_B2G_RIL
CPPSRCS += \
nsDOMWifiEvent.cpp \
$(NULL)
endif
deleted file mode 100644
--- a/content/events/src/nsDOMApplicationEvent.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this file,
-* You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsDOMApplicationEvent.h"
-#include "nsContentUtils.h"
-#include "DictionaryHelpers.h"
-#include "nsDOMClassInfoID.h"
-
-DOMCI_DATA(MozApplicationEvent, nsDOMMozApplicationEvent)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMozApplicationEvent)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMozApplicationEvent, nsDOMEvent)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mApplication)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMozApplicationEvent, nsDOMEvent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mApplication)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMMozApplicationEvent)
- NS_INTERFACE_MAP_ENTRY(nsIDOMMozApplicationEvent)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozApplicationEvent)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
-
-NS_IMPL_ADDREF_INHERITED(nsDOMMozApplicationEvent, nsDOMEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMMozApplicationEvent, nsDOMEvent)
-
-NS_IMETHODIMP
-nsDOMMozApplicationEvent::GetApplication(mozIDOMApplication** aApplication)
-{
- NS_IF_ADDREF(*aApplication = mApplication);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMozApplicationEvent::InitMozApplicationEvent(const nsAString& aType,
- bool aCanBubble,
- bool aCancelable,
- mozIDOMApplication* aApplication)
-{
- nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mApplication = aApplication;
-
- return NS_OK;
-}
-
-nsresult
-nsDOMMozApplicationEvent::InitFromCtor(const nsAString& aType, JSContext* aCx, jsval* aVal)
-{
- mozilla::dom::MozApplicationEventInit d;
- nsresult rv = d.Init(aCx, aVal);
- NS_ENSURE_SUCCESS(rv, rv);
- return InitMozApplicationEvent(aType, d.bubbles, d.cancelable, d.application);
-}
-
-nsresult
-NS_NewDOMMozApplicationEvent(nsIDOMEvent** aInstancePtrResult,
- nsPresContext* aPresContext,
- nsEvent* aEvent)
-{
- nsDOMMozApplicationEvent* e = new nsDOMMozApplicationEvent(aPresContext, aEvent);
- return CallQueryInterface(e, aInstancePtrResult);
-}
deleted file mode 100644
--- a/content/events/src/nsDOMApplicationEvent.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this file,
-* You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDOMApplicationEvent_h__
-#define nsDOMApplicationEvent_h__
-
-#include "nsIDOMApplicationRegistry.h"
-#include "nsDOMEvent.h"
-
-class nsDOMMozApplicationEvent : public nsDOMEvent,
- public nsIDOMMozApplicationEvent
-{
-public:
- nsDOMMozApplicationEvent(nsPresContext* aPresContext, nsEvent* aEvent)
- : nsDOMEvent(aPresContext, aEvent) {}
-
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMMozApplicationEvent, nsDOMEvent)
- // Forward to base class
- NS_FORWARD_TO_NSDOMEVENT
-
- NS_DECL_NSIDOMMOZAPPLICATIONEVENT
-
- virtual nsresult InitFromCtor(const nsAString& aType, JSContext* aCx, jsval* aVal);
-
-private:
- nsCOMPtr<mozIDOMApplication> mApplication;
-};
-
-#endif // nsDOMContactChangeEvent_h__
\ No newline at end of file
deleted file mode 100644
--- a/content/events/src/nsDOMDeviceLightEvent.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsDOMClassInfoID.h"
-#include "nsDOMDeviceLightEvent.h"
-#include "DictionaryHelpers.h"
-
-NS_IMPL_ADDREF_INHERITED(nsDOMDeviceLightEvent, nsDOMEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMDeviceLightEvent, nsDOMEvent)
-
-DOMCI_DATA(DeviceLightEvent, nsDOMDeviceLightEvent)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMDeviceLightEvent)
- NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceLightEvent)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceLightEvent)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
-
-NS_IMETHODIMP
-nsDOMDeviceLightEvent::InitDeviceLightEvent(const nsAString & aEventTypeArg,
- bool aCanBubbleArg,
- bool aCancelableArg,
- double aValue)
-{
- nsresult rv = nsDOMEvent::InitEvent(aEventTypeArg, aCanBubbleArg, aCancelableArg);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mValue = aValue;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDeviceLightEvent::GetValue(double *aValue)
-{
- NS_ENSURE_ARG_POINTER(aValue);
- *aValue = mValue;
- return NS_OK;
-}
-
-nsresult
-nsDOMDeviceLightEvent::InitFromCtor(const nsAString& aType,
- JSContext* aCx, jsval* aVal)
-{
- mozilla::dom::DeviceLightEventInit d;
- nsresult rv = d.Init(aCx, aVal);
- NS_ENSURE_SUCCESS(rv, rv);
- return InitDeviceLightEvent(aType, d.bubbles, d.cancelable, d.value);
-}
-
-nsresult
-NS_NewDOMDeviceLightEvent(nsIDOMEvent** aInstancePtrResult,
- nsPresContext* aPresContext,
- nsEvent *aEvent)
-{
- NS_ENSURE_ARG_POINTER(aInstancePtrResult);
- nsDOMDeviceLightEvent* it = new nsDOMDeviceLightEvent(aPresContext, aEvent);
- return CallQueryInterface(it, aInstancePtrResult);
-}
deleted file mode 100644
--- a/content/events/src/nsDOMDeviceLightEvent.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDOMDeviceLightEvent_h__
-#define nsDOMDeviceLightEvent_h__
-
-#include "nsIDOMDeviceLightEvent.h"
-#include "nsDOMEvent.h"
-
-class nsDOMDeviceLightEvent
- : public nsDOMEvent
- , public nsIDOMDeviceLightEvent
-{
-public:
-
- nsDOMDeviceLightEvent(nsPresContext* aPresContext, nsEvent* aEvent)
- : nsDOMEvent(aPresContext, aEvent),
- mValue(0) {}
-
- NS_DECL_ISUPPORTS_INHERITED
-
- // Forward to nsDOMEvent
- NS_FORWARD_TO_NSDOMEVENT
-
- // nsIDOMDeviceLightEvent Interface
- NS_DECL_NSIDOMDEVICELIGHTEVENT
-
- virtual nsresult InitFromCtor(const nsAString& aType,
- JSContext* aCx,
- jsval* aVal);
-protected:
- double mValue;
-};
-
-#endif
deleted file mode 100644
--- a/content/events/src/nsDOMDeviceOrientationEvent.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsDOMClassInfoID.h"
-#include "nsDOMDeviceOrientationEvent.h"
-
-NS_IMPL_ADDREF_INHERITED(nsDOMDeviceOrientationEvent, nsDOMEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMDeviceOrientationEvent, nsDOMEvent)
-
-DOMCI_DATA(DeviceOrientationEvent, nsDOMDeviceOrientationEvent)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMDeviceOrientationEvent)
- NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceOrientationEvent)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceOrientationEvent)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
-
-NS_IMETHODIMP nsDOMDeviceOrientationEvent::InitDeviceOrientationEvent(const nsAString & aEventTypeArg,
- bool aCanBubbleArg,
- bool aCancelableArg,
- double aAlpha,
- double aBeta,
- double aGamma,
- bool aAbsolute)
-{
- nsresult rv = nsDOMEvent::InitEvent(aEventTypeArg, aCanBubbleArg, aCancelableArg);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mAlpha = aAlpha;
- mBeta = aBeta;
- mGamma = aGamma;
- mAbsolute = aAbsolute;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP nsDOMDeviceOrientationEvent::GetAlpha(double *aAlpha)
-{
- NS_ENSURE_ARG_POINTER(aAlpha);
-
- *aAlpha = mAlpha;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsDOMDeviceOrientationEvent::GetBeta(double *aBeta)
-{
- NS_ENSURE_ARG_POINTER(aBeta);
-
- *aBeta = mBeta;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsDOMDeviceOrientationEvent::GetGamma(double *aGamma)
-{
- NS_ENSURE_ARG_POINTER(aGamma);
-
- *aGamma = mGamma;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsDOMDeviceOrientationEvent::GetAbsolute(bool *aAbsolute)
-{
- NS_ENSURE_ARG_POINTER(aAbsolute);
-
- *aAbsolute = mAbsolute;
- return NS_OK;
-}
-
-nsresult NS_NewDOMDeviceOrientationEvent(nsIDOMEvent** aInstancePtrResult,
- nsPresContext* aPresContext,
- nsEvent *aEvent)
-{
- NS_ENSURE_ARG_POINTER(aInstancePtrResult);
-
- nsDOMDeviceOrientationEvent* it = new nsDOMDeviceOrientationEvent(aPresContext, aEvent);
- if (nsnull == it) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- return CallQueryInterface(it, aInstancePtrResult);
-}
deleted file mode 100644
--- a/content/events/src/nsDOMDeviceOrientationEvent.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDOMDeviceOrientationEvent_h__
-#define nsDOMDeviceOrientationEvent_h__
-
-#include "nsIDOMDeviceOrientationEvent.h"
-#include "nsDOMEvent.h"
-
-class nsDOMDeviceOrientationEvent : public nsDOMEvent,
- public nsIDOMDeviceOrientationEvent
-{
-public:
-
- nsDOMDeviceOrientationEvent(nsPresContext* aPresContext, nsEvent* aEvent)
- : nsDOMEvent(aPresContext, aEvent),
- mAlpha(0),
- mBeta(0),
- mGamma(0),
- mAbsolute(true) {}
-
- NS_DECL_ISUPPORTS_INHERITED
-
- // Forward to nsDOMEvent
- NS_FORWARD_TO_NSDOMEVENT
-
- // nsIDOMDeviceOrientationEvent Interface
- NS_DECL_NSIDOMDEVICEORIENTATIONEVENT
-
-protected:
- double mAlpha, mBeta, mGamma;
- bool mAbsolute;
-};
-
-#endif
--- a/content/events/test/test_eventctors.html
+++ b/content/events/test/test_eventctors.html
@@ -420,16 +420,34 @@ is(receivedEvent, e, "Wrong event!");
// DeviceLightEvent
e = new DeviceLightEvent("hello", {value: 1} );
ok(e.type, "hello", "Wrong event type!");
ok(!e.isTrusted, "Event should not be trusted");
is(e.value, 1, "value should be 1");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
+// DeviceOrientationEvent
+e = new DeviceOrientationEvent("hello");
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.alpha, 0);
+is(e.beta, 0);
+is(e.gamma, 0);
+is(e.absolute, false);
+
+e = new DeviceOrientationEvent("hello", { alpha: 1, beta: 2, gamma: 3, absolute: true } );
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.alpha, 1);
+is(e.beta, 2);
+is(e.gamma, 3);
+is(e.absolute, true);
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
// MouseEvent
try {
e = new MouseEvent();
} catch(exp) {
ex = true;
}
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -758,21 +758,32 @@ ChannelMediaResource::CacheClientSeek(PR
CloseChannel();
if (aResume) {
NS_ASSERTION(mSuspendCount > 0, "Too many resumes!");
// No need to mess with the channel, since we're making a new one
--mSuspendCount;
}
+ mOffset = aOffset;
+
+ if (mSuspendCount > 0) {
+ // Close the existing channel to force the channel to be recreated at
+ // the correct offset upon resume.
+ if (mChannel) {
+ mIgnoreClose = true;
+ CloseChannel();
+ }
+ return NS_OK;
+ }
+
nsresult rv = RecreateChannel();
if (NS_FAILED(rv))
return rv;
- mOffset = aOffset;
return OpenChannel(nsnull);
}
nsresult
ChannelMediaResource::CacheClientSuspend()
{
Suspend(false);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -293,18 +293,16 @@
#include "nsIDOMMozCSSKeyframesRule.h"
#include "nsIDOMCSSPrimitiveValue.h"
#include "nsIDOMCSSStyleRule.h"
#include "nsIDOMCSSStyleSheet.h"
#include "nsDOMCSSValueList.h"
#define MOZ_GENERATED_EVENTS_INCLUDES
#include "GeneratedEvents.h"
#undef MOZ_GENERATED_EVENTS_INCLUDES
-#include "nsIDOMDeviceLightEvent.h"
-#include "nsIDOMDeviceOrientationEvent.h"
#include "nsIDOMDeviceMotionEvent.h"
#include "nsIDOMRange.h"
#include "nsIDOMNodeIterator.h"
#include "nsIDOMTreeWalker.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULElement.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIDOMCrypto.h"
@@ -810,30 +808,24 @@ static nsDOMClassInfoData sClassInfoData
NS_DEFINE_CLASSINFO_DATA(DragEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CompositionEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
- // Device Light
- NS_DEFINE_CLASSINFO_DATA(DeviceLightEvent, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
#define MOZ_GENERATED_EVENT_LIST
#define MOZ_GENERATED_EVENT(_event_interface) \
NS_DEFINE_CLASSINFO_DATA(_event_interface, nsDOMGenericSH, \
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#include "GeneratedEvents.h"
#undef MOZ_GENERATED_EVENT_LIST
- // Device Orientation
- NS_DEFINE_CLASSINFO_DATA(DeviceOrientationEvent, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DeviceMotionEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DeviceAcceleration, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
// Misc HTML classes
@@ -1636,18 +1628,16 @@ static nsDOMClassInfoData sClassInfoData
NS_DEFINE_CLASSINFO_DATA(MediaQueryList, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MutationObserver, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MutationRecord, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozSettingsEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
- NS_DEFINE_CLASSINFO_DATA(MozApplicationEvent, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
#ifdef MOZ_B2G_RIL
NS_DEFINE_CLASSINFO_DATA(MozWifiStatusChangeEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozWifiConnectionInfoEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Telephony, nsEventTargetSH,
EVENTTARGET_SCRIPTABLE_FLAGS)
@@ -1722,20 +1712,18 @@ static const nsContractIDMapData kConstr
nsIDOMEvent* e = nsnull; \
nsresult rv = NS_NewDOM##_class(&e, nsnull, nsnull); \
*aInstancePtrResult = e; \
return rv; \
}
NS_DEFINE_EVENT_CTOR(Event)
NS_DEFINE_EVENT_CTOR(MozSettingsEvent)
-NS_DEFINE_EVENT_CTOR(MozApplicationEvent)
NS_DEFINE_EVENT_CTOR(UIEvent)
NS_DEFINE_EVENT_CTOR(MouseEvent)
-NS_DEFINE_EVENT_CTOR(DeviceLightEvent)
#ifdef MOZ_B2G_RIL
NS_DEFINE_EVENT_CTOR(MozWifiStatusChangeEvent)
NS_DEFINE_EVENT_CTOR(MozWifiConnectionInfoEvent)
#endif
#define MOZ_GENERATED_EVENT_LIST
#define MOZ_GENERATED_EVENT(_event_interface) \
NS_DEFINE_EVENT_CTOR(_event_interface)
@@ -1770,20 +1758,18 @@ struct nsConstructorFuncMapData
static const nsConstructorFuncMapData kConstructorFuncMap[] =
{
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob, nsDOMMultipartFile::NewBlob)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFileFile::NewFile)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozBlobBuilder, NS_NewBlobBuilder)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozSettingsEvent)
- NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozApplicationEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
- NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(DeviceLightEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(StorageEvent)
#ifdef MOZ_B2G_RIL
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiStatusChangeEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiConnectionInfoEvent)
#endif
#define MOZ_GENERATED_EVENT_LIST
#define MOZ_GENERATED_EVENT(_event_interface) \
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(_event_interface)
@@ -2595,35 +2581,25 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(PopupBlockedEvent, nsIDOMPopupBlockedEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMPopupBlockedEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
- DOM_CLASSINFO_MAP_BEGIN(DeviceLightEvent, nsIDOMDeviceLightEvent)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceLightEvent)
- DOM_CLASSINFO_EVENT_MAP_ENTRIES
- DOM_CLASSINFO_MAP_END
-
#define MOZ_GENERATED_EVENT_LIST
#define MOZ_GENERATED_EVENT(_event_interface) \
DOM_CLASSINFO_MAP_BEGIN(_event_interface, nsIDOM##_event_interface) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOM##_event_interface) \
DOM_CLASSINFO_EVENT_MAP_ENTRIES \
DOM_CLASSINFO_MAP_END
#include "GeneratedEvents.h"
#undef MOZ_GENERATED_EVENT_LIST
- DOM_CLASSINFO_MAP_BEGIN(DeviceOrientationEvent, nsIDOMDeviceOrientationEvent)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceOrientationEvent)
- DOM_CLASSINFO_EVENT_MAP_ENTRIES
- DOM_CLASSINFO_MAP_END
-
DOM_CLASSINFO_MAP_BEGIN(DeviceMotionEvent, nsIDOMDeviceMotionEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceMotionEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(DeviceAcceleration, nsIDOMDeviceAcceleration)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceAcceleration)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
@@ -4404,21 +4380,16 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationRecord)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozSettingsEvent, nsIDOMMozSettingsEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSettingsEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
- DOM_CLASSINFO_MAP_BEGIN(MozApplicationEvent, nsIDOMMozApplicationEvent)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozApplicationEvent)
- DOM_CLASSINFO_EVENT_MAP_ENTRIES
- DOM_CLASSINFO_MAP_END
-
#ifdef MOZ_B2G_RIL
DOM_CLASSINFO_MAP_BEGIN(MozWifiStatusChangeEvent, nsIDOMMozWifiStatusChangeEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWifiStatusChangeEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozWifiConnectionInfoEvent, nsIDOMMozWifiConnectionInfoEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWifiConnectionInfoEvent)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -38,22 +38,20 @@ DOMCI_CLASS(Event)
DOMCI_CLASS(MutationEvent)
DOMCI_CLASS(UIEvent)
DOMCI_CLASS(MouseEvent)
DOMCI_CLASS(MouseScrollEvent)
DOMCI_CLASS(DragEvent)
DOMCI_CLASS(KeyboardEvent)
DOMCI_CLASS(CompositionEvent)
DOMCI_CLASS(PopupBlockedEvent)
-DOMCI_CLASS(DeviceLightEvent)
#define MOZ_GENERATED_EVENT_LIST
#define MOZ_GENERATED_EVENT(_event_interface) DOMCI_CLASS(_event_interface)
#include "GeneratedEvents.h"
#undef MOZ_GENERATED_EVENT_LIST
-DOMCI_CLASS(DeviceOrientationEvent)
DOMCI_CLASS(DeviceMotionEvent)
DOMCI_CLASS(DeviceAcceleration)
DOMCI_CLASS(DeviceRotationRate)
// HTML classes
DOMCI_CLASS(HTMLDocument)
DOMCI_CLASS(HTMLOptionsCollection)
DOMCI_CLASS(HTMLCollection)
@@ -504,18 +502,16 @@ DOMCI_CLASS(MozCSSKeyframesRule)
DOMCI_CLASS(MediaQueryList)
DOMCI_CLASS(MutationObserver)
DOMCI_CLASS(MutationRecord)
DOMCI_CLASS(MozSettingsEvent)
-DOMCI_CLASS(MozApplicationEvent)
-
#ifdef MOZ_B2G_RIL
DOMCI_CLASS(MozWifiStatusChangeEvent)
DOMCI_CLASS(MozWifiConnectionInfoEvent)
DOMCI_CLASS(Telephony)
DOMCI_CLASS(TelephonyCall)
DOMCI_CLASS(CallEvent)
DOMCI_CLASS(MozVoicemail)
DOMCI_CLASS(MozVoicemailEvent)
--- a/dom/contacts/fallback/ContactService.jsm
+++ b/dom/contacts/fallback/ContactService.jsm
@@ -62,16 +62,17 @@ let DOMContactManager = {
this._messages = null;
if (this._db)
this._db.close();
this._db = null;
},
receiveMessage: function(aMessage) {
debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
+ let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
let msg = aMessage.json;
/*
* Sorting the contacts by sortBy field. sortBy can either be familyName or givenName.
* If 2 entries have the same sortyBy field or no sortBy field is present, we continue
* sorting with the other sortyBy field.
*/
function sortfunction(a, b){
@@ -119,37 +120,37 @@ let DOMContactManager = {
if (msg.findOptions.sortOrder !== 'undefined' && msg.findOptions.sortBy !== 'undefined') {
debug('sortBy: ' + msg.findOptions.sortBy + ', sortOrder: ' + msg.findOptions.sortOrder );
result.sort(sortfunction);
if (msg.findOptions.filterLimit)
result = result.slice(0, msg.findOptions.filterLimit);
}
debug("result:" + JSON.stringify(result));
- ppmm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
+ mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
}.bind(this),
- function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
+ function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
msg.findOptions);
break;
case "Contact:Save":
this._db.saveContact(
msg.contact,
- function() { ppmm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.contact.id }); }.bind(this),
- function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+ function() { mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.contact.id }); }.bind(this),
+ function(aErrorMsg) { mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
);
break;
case "Contact:Remove":
this._db.removeContact(
msg.id,
- function() { ppmm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.id }); }.bind(this),
- function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+ function() { mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.id }); }.bind(this),
+ function(aErrorMsg) { mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
);
break;
case "Contacts:Clear":
this._db.clear(
- function() { ppmm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
- function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+ function() { mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
+ function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
);
}
}
}
DOMContactManager.init();
--- a/dom/contacts/tests/Makefile.in
+++ b/dom/contacts/tests/Makefile.in
@@ -11,12 +11,13 @@ relativesrcdir = dom/contacts/tests
include $(DEPTH)/config/autoconf.mk
DIRS = \
$(NULL)
MOCHITEST_FILES = \
test_contacts_basics.html \
+ test_contacts_events.html \
$(NULL)
include $(topsrcdir)/config/rules.mk
--- a/dom/interfaces/apps/Makefile.in
+++ b/dom/interfaces/apps/Makefile.in
@@ -12,11 +12,12 @@ include $(DEPTH)/config/autoconf.mk
MODULE = dom
XPIDL_MODULE = dom_apps
GRE_MODULE = 1
XPIDLSRCS = \
nsIDOMApplicationRegistry.idl \
nsIAppsService.idl \
+ nsIDOMMozApplicationEvent.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk
--- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
+++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
@@ -1,14 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "domstubs.idl"
-#include "nsIDOMEvent.idl"
#include "nsIDOMEventTarget.idl"
interface nsIDOMDOMRequest;
interface nsIArray;
[scriptable, uuid(9583b825-46b1-4e8f-bb48-9fed660a95e6)]
interface mozIDOMApplication : nsISupports
{
@@ -38,32 +37,16 @@ interface mozIDOMApplication : nsISuppo
*/
attribute nsIDOMEventListener onprogress;
/* startPoint will be used when several launch_path exists for an app */
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
nsIDOMDOMRequest uninstall();
};
-[scriptable, builtinclass, uuid(8f2bfba8-f10e-4f63-a5e0-7a7056e1dbe6)]
-interface nsIDOMMozApplicationEvent : nsIDOMEvent
-{
- readonly attribute mozIDOMApplication application;
-
- [noscript] void initMozApplicationEvent(in DOMString aType,
- in boolean aCanBubble,
- in boolean aCancelable,
- in mozIDOMApplication aApplication);
-};
-
-dictionary MozApplicationEventInit : EventInit
-{
- mozIDOMApplication application;
-};
-
[scriptable, uuid(bd304874-d532-4e13-8034-544211445583)]
interface mozIDOMApplicationMgmt : nsISupports
{
/**
* the request will return the all the applications installed. Only accessible
* to privileged callers.
*/
nsIDOMDOMRequest getAll();
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/apps/nsIDOMMozApplicationEvent.idl
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIDOMEvent.idl"
+
+interface mozIDOMApplication;
+
+[scriptable, builtinclass, uuid(8f2bfba8-f10e-4f63-a5e0-7a7056e1dbe6)]
+interface nsIDOMMozApplicationEvent : nsIDOMEvent
+{
+ readonly attribute mozIDOMApplication application;
+
+ [noscript] void initMozApplicationEvent(in DOMString aType,
+ in boolean aCanBubble,
+ in boolean aCancelable,
+ in mozIDOMApplication aApplication);
+};
+
+dictionary MozApplicationEventInit : EventInit
+{
+ mozIDOMApplication application;
+};
--- a/dom/interfaces/events/nsIDOMDeviceOrientationEvent.idl
+++ b/dom/interfaces/events/nsIDOMDeviceOrientationEvent.idl
@@ -36,8 +36,15 @@ interface nsIDOMDeviceOrientationEvent :
*/
readonly attribute double alpha;
readonly attribute double beta;
readonly attribute double gamma;
readonly attribute boolean absolute;
};
+dictionary DeviceOrientationEventInit : EventInit
+{
+ double alpha;
+ double beta;
+ double gamma;
+ boolean absolute;
+};
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -199,20 +199,16 @@ nsresult
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
nsresult
NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsCompositionEvent *aEvent);
nsresult
NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
nsresult
NS_NewDOMPopupBlockedEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
nsresult
-NS_NewDOMDeviceOrientationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
-nsresult
-NS_NewDOMDeviceLightEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
-nsresult
NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
nsresult
NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
nsresult
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
nsresult
NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
nsresult
--- a/dom/mms/src/ril/MmsPduHelper.jsm
+++ b/dom/mms/src/ril/MmsPduHelper.jsm
@@ -21,16 +21,23 @@ function translatePduErrorToStatus(error
if ((error >= MMS_PDU_ERROR_TRANSIENT_FAILURE)
&& (error < MMS_PDU_ERROR_PERMANENT_FAILURE)) {
return MMS_PDU_STATUS_DEFERRED;
}
return MMS_PDU_STATUS_UNRECOGNISED;
}
+function defineLazyRegExp(obj, name, pattern) {
+ obj.__defineGetter__(name, function() {
+ delete obj[name];
+ return obj[name] = new RegExp(pattern);
+ });
+}
+
/**
* Internal decoding function for boolean values.
*
* Boolean-value = Yes | No
* Yes = <Octet 128>
* No = <Octet 129>
*/
let BooleanValue = {
@@ -75,36 +82,111 @@ let Address = {
* A wrapped object to store encoded raw data.
*
* @return An object of two string-typed attributes: address and type.
*/
decode: function decode(data) {
let str = EncodedStringValue.decode(data);
let result;
- if (((result = str.match(/^(\+?[\d.-]+)\/TYPE=(PLMN)$/)) != null)
- || ((result = str.match(/^(\d{1,3}(?:\.\d{1,3}){3})\/TYPE=(IPv4)$/)) != null)
- || ((result = str.match(/^([\da-fA-F]{4}(?::[\da-fA-F]{4}){7})\/TYPE=(IPv6)$/)) != null)
- || ((result = str.match(/^([\w\+\-.%]+)\/TYPE=(\w+)$/)) != null)) {
+ if (((result = str.match(this.REGEXP_DECODE_PLMN)) != null)
+ || ((result = str.match(this.REGEXP_DECODE_IPV4)) != null)
+ || ((result = str.match(this.REGEXP_DECODE_IPV6)) != null)
+ || ((result = str.match(this.REGEXP_DECODE_CUSTOM)) != null)) {
return {address: result[1], type: result[2]};
}
let type;
- if (str.match(/^[\+*#]\d+$/)) {
+ if (str.match(this.REGEXP_NUM)) {
type = "num";
- } else if (str.match(/^\w+$/)) {
+ } else if (str.match(this.REGEXP_ALPHANUM)) {
type = "alphanum";
+ } else if (str.indexOf("@") > 0) {
+ // E-mail should match the definition of `mailbox` as described in section
+ // 3.4 of RFC2822, but excluding the obsolete definitions as indicated by
+ // the "obs-" prefix. Here we match only a `@` character.
+ type = "email";
} else {
- type = "unknown";
+ throw new WSP.CodeError("Address: invalid address");
}
return {address: str, type: type};
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object of two string-typed attributes: address and type.
+ */
+ encode: function encode(data, value) {
+ if (!value || !value.type || !value.address) {
+ throw new WSP.CodeError("Address: invalid value");
+ }
+
+ let str;
+ switch (value.type) {
+ case "email":
+ if (value.address.indexOf("@") > 0) {
+ str = value.address;
+ }
+ break;
+ case "num":
+ if (value.address.match(this.REGEXP_NUM)) {
+ str = value.address;
+ }
+ break;
+ case "alphanum":
+ if (value.address.match(this.REGEXP_ALPHANUM)) {
+ str = value.address;
+ }
+ break;
+ case "IPv4":
+ if (value.address.match(this.REGEXP_ENCODE_IPV4)) {
+ str = value.address + "/TYPE=IPv4";
+ }
+ break;
+ case "IPv6":
+ if (value.address.match(this.REGEXP_ENCODE_IPV6)) {
+ str = value.address + "/TYPE=IPv6";
+ }
+ break;
+ case "PLMN":
+ if (value.address.match(this.REGEXP_ENCODE_PLMN)) {
+ str = value.address + "/TYPE=PLMN";
+ }
+ break;
+ default:
+ if (value.type.match(this.REGEXP_ENCODE_CUSTOM_TYPE)
+ && value.address.match(this.REGEXP_ENCODE_CUSTOM_ADDR)) {
+ str = value.address + "/TYPE=" + value.type;
+ }
+ break;
+ }
+
+ if (!str) {
+ throw new WSP.CodeError("Address: invalid value: " + JSON.stringify(value));
+ }
+
+ EncodedStringValue.encode(data, str);
+ },
};
+defineLazyRegExp(Address, "REGEXP_DECODE_PLMN", "^(\\+?[\\d.-]+)\\/TYPE=(PLMN)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_IPV4", "^(\\d{1,3}(?:\\.\\d{1,3}){3})\\/TYPE=(IPv4)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_IPV6", "^([\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7})\\/TYPE=(IPv6)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_CUSTOM", "^([\\w\\+\\-.%]+)\\/TYPE=(\\w+)$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_PLMN", "^\\+?[\\d.-]+$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_IPV4", "^\\d{1,3}(?:\\.\\d{1,3}){3}$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_IPV6", "^[\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7}$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_TYPE", "^\\w+$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_ADDR", "^[\\w\\+\\-.%]+$");
+defineLazyRegExp(Address, "REGEXP_NUM", "^[\\+*#]\\d+$");
+defineLazyRegExp(Address, "REGEXP_ALPHANUM", "^\\w+$");
+
/**
* Header-field = MMS-header | Application-header
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.2
*/
let HeaderField = {
/**
* @param data
@@ -230,16 +312,30 @@ let ContentClassValue = {
decode: function decode(data) {
let value = WSP.Octet.decode(data);
if ((value >= 128) && (value <= 135)) {
return value;
}
throw new WSP.CodeError("Content-class-value: invalid class " + value);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * A numeric content class value to be encoded.
+ */
+ encode: function encode(data, value) {
+ if ((value < 128) || (value > 135)) {
+ throw new WSP.CodeError("Content-class-value: invalid class " + value);
+ }
+
+ WSP.Octet.encode(data, value);
+ },
};
/**
* When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
*
* Content-location-value = Uri-value
*
* When used in the M-Mbox-Delete.conf and M-Delete.conf PDU:
@@ -396,16 +492,40 @@ let Parameter = {
params = {};
}
params[param.name] = param.value;
}
}
return params;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param param
+ * An object containing two attributes: `name` and `value`.
+ * @param options
+ * Extra context for encoding.
+ */
+ encode: function encode(data, param, options) {
+ if (!param || !param.name) {
+ throw new WSP.CodeError("Parameter-name: empty param name");
+ }
+
+ let entry = MMS_WELL_KNOWN_PARAMS[param.name.toLowerCase()];
+ if (entry) {
+ WSP.ShortInteger.encode(data, entry.number);
+ } else {
+ WSP.TextString.encode(data, param.name);
+ }
+
+ WSP.encodeAlternatives(data, param.value, options,
+ WSP.ConstrainedEncoding, WSP.TextString);
+ },
};
/**
* The Char-set values are registered by IANA as MIBEnum value and SHALL be
* encoded as Integer-value.
*
* Encoded-string-value = Text-string | Value-length Char-set Text-string
*
@@ -479,16 +599,73 @@ let EncodedStringValue = {
let begin = data.offset;
try {
return WSP.TextString.decode(data);
} catch (e) {
data.offset = begin;
return this.decodeCharsetEncodedString(data);
}
},
+
+ /**
+ * Always encode target string with UTF-8 encoding.
+ *
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param str
+ * A string.
+ */
+ encodeCharsetEncodedString: function encodeCharsetEncodedString(data, str) {
+ let conv = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Ci.nsIScriptableUnicodeConverter);
+ // `When the text string cannot be represented as us-ascii, the character
+ // set SHALL be encoded as utf-8(IANA MIBenum 106) which has unique byte
+ // ordering.` ~ OMA-TS-MMS_CONF-V1_3-20110913-A clause 10.2.1
+ conv.charset = "UTF-8";
+
+ let raw;
+ try {
+ raw = conv.convertToByteArray(str);
+ } catch (e) {
+ throw new WSP.CodeError("Charset-encoded-string: " + e.message);
+ }
+
+ let length = raw.length + 2; // Charset number and NUL character
+ // Prepend <Octet 127> if necessary.
+ if (raw[0] >= 128) {
+ ++length;
+ }
+
+ WSP.ValueLength.encode(data, length);
+
+ let entry = WSP.WSP_WELL_KNOWN_CHARSETS["utf-8"];
+ WSP.IntegerValue.encode(data, entry.number);
+
+ if (raw[0] >= 128) {
+ WSP.Octet.encode(data, 127);
+ }
+ WSP.Octet.encodeMultiple(data, raw);
+ WSP.Octet.encode(data, 0);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param str
+ * A string.
+ */
+ encode: function encode(data, str) {
+ let begin = data.offset;
+ try {
+ WSP.TextString.encode(data, str);
+ } catch (e) {
+ data.offset = begin;
+ this.encodeCharsetEncodedString(data, str);
+ }
+ },
};
/**
* Expiry-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value)
* Absolute-token = <Octet 128>
* Relative-token = <Octet 129>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.20
@@ -519,16 +696,49 @@ let ExpiryValue = {
}
if (data.offset != end) {
data.offset = end;
}
return result;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * A Date object for absolute expiry or an integer for relative one.
+ */
+ encode: function encode(data, value) {
+ let isDate, begin = data.offset;
+ if (value instanceof Date) {
+ isDate = true;
+ WSP.DateValue.encode(data, value);
+ } else if (typeof value == "number") {
+ isDate = false;
+ WSP.DeltaSecondsValue.encode(data, value);
+ } else {
+ throw new CodeError("Expiry-value: invalid value type");
+ }
+
+ // Calculate how much octets will be written and seek back.
+ // TODO: use memmove, see bug 730873
+ let len = data.offset - begin;
+ data.offset = begin;
+
+ WSP.ValueLength.encode(data, len + 1);
+ if (isDate) {
+ WSP.Octet.encode(data, 128);
+ WSP.DateValue.encode(data, value);
+ } else {
+ WSP.Octet.encode(data, 129);
+ WSP.DeltaSecondsValue.encode(data, value);
+ }
+ },
};
/**
* From-value = Value-length (Address-present-token Address | Insert-address-token)
* Address-present-token = <Octet 128>
* Insert-address-token = <Octet 129>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.21
@@ -558,16 +768,41 @@ let FromValue = {
}
if (data.offset != end) {
data.offset = end;
}
return result;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * A Address-value or null for MMS Proxy-Relay Insert-Address mode.
+ */
+ encode: function encode(data, value) {
+ if (!value) {
+ WSP.ValueLength.encode(data, 1);
+ WSP.Octet.encode(data, 129);
+ return;
+ }
+
+ // Calculate how much octets will be written and seek back.
+ // TODO: use memmove, see bug 730873
+ let begin = data.offset;
+ Address.encode(data, value);
+ let len = data.offset - begin;
+ data.offset = begin;
+
+ WSP.ValueLength.encode(data, len + 1);
+ WSP.Octet.encode(data, 128);
+ Address.encode(data, value);
+ },
};
/**
* Previously-sent-by-value = Value-length Forwarded-count-value Address
* Forwarded-count-value = Integer-value
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.23
*/
@@ -631,31 +866,30 @@ let PreviouslySentDateValue = {
* Personal = <Octet 128>
* Advertisement = <Octet 129>
* Informational = <Octet 130>
* Auto = <Octet 131>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.27
*/
let MessageClassValue = {
+ WELL_KNOWN_CLASSES: ["personal", "advertisement", "informational", "auto"],
+
/**
* @param data
* A wrapped object containing raw PDU data.
*
* @return A decoded string.
*
* @throws CodeError if decoded value is not in the range 128..131.
*/
decodeClassIdentifier: function decodeClassIdentifier(data) {
let value = WSP.Octet.decode(data);
- switch (value) {
- case 128: return "personal";
- case 129: return "advertisement";
- case 130: return "informational";
- case 131: return "auto";
+ if ((value >= 128) && (value < (128 + this.WELL_KNOWN_CLASSES.length))) {
+ return this.WELL_KNOWN_CLASSES[value - 128];
}
throw new WSP.CodeError("Class-identifier: invalid id " + value);
},
/**
* @param data
* A wrapped object containing raw PDU data.
@@ -666,16 +900,30 @@ let MessageClassValue = {
let begin = data.offset;
try {
return this.decodeClassIdentifier(data);
} catch (e) {
data.offset = begin;
return WSP.TokenText.decode(data);
}
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param klass
+ */
+ encode: function encode(data, klass) {
+ let index = this.WELL_KNOWN_CLASSES.indexOf(klass.toLowerCase());
+ if (index >= 0) {
+ WSP.Octet.encode(data, index + 128);
+ } else {
+ WSP.TokenText.encode(data, klass);
+ }
+ },
};
/**
* Message-type-value = <Octet 128..151>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.30
*/
let MessageTypeValue = {
@@ -743,16 +991,40 @@ let MmFlagsValue = {
result.text = EncodedStringValue.decode(data);
if (data.offset != end) {
data.offset = end;
}
return result;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object containing an integer `type` and an string-typed
+ * `text` attributes.
+ */
+ encode: function encode(data, value) {
+ if ((value.type < 128) || (value.type > 130)) {
+ throw new WSP.CodeError("MM-flags-value: invalid type " + value.type);
+ }
+
+ // Calculate how much octets will be written and seek back.
+ // TODO: use memmove, see bug 730873
+ let begin = data.offset;
+ EncodedStringValue.encode(data, value.text);
+ let len = data.offset - begin;
+ data.offset = begin;
+
+ WSP.ValueLength.encode(data, len + 1);
+ WSP.Octet.encode(data, value.type);
+ EncodedStringValue.encode(data, value.text);
+ },
};
/**
* MM-state-value = Draft | Sent | New | Retrieved | Forwarded
* Draft = <Octet 128>
* Sent = <Octet 129>
* New = <Octet 130>
* Retrieved = <Octet 131>
@@ -772,16 +1044,32 @@ let MmStateValue = {
decode: function decode(data) {
let state = WSP.Octet.decode(data);
if ((state >= 128) && (state <= 132)) {
return state;
}
throw new WSP.CodeError("MM-state-value: invalid state " + state);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param state
+ * A numeric state value to be encoded.
+ *
+ * @throws CodeError if state is not in the range 128..132.
+ */
+ encode: function encode(data, state) {
+ if ((state < 128) || (state > 132)) {
+ throw new WSP.CodeError("MM-state-value: invalid state " + state);
+ }
+
+ WSP.Octet.encode(data, state);
+ },
};
/**
* Priority-value = Low | Normal | High
* Low = <Octet 128>
* Normal = <Octet 129>
* High = <Octet 130>
*
@@ -799,16 +1087,30 @@ let PriorityValue = {
decode: function decode(data) {
let priority = WSP.Octet.decode(data);
if ((priority >= 128) && (priority <= 130)) {
return priority;
}
throw new WSP.CodeError("Priority-value: invalid priority " + priority);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param priority
+ * A numeric priority value to be encoded.
+ */
+ encode: function encode(data, priority) {
+ if ((priority < 128) || (priority > 130)) {
+ throw new WSP.CodeError("Priority-value: invalid priority " + priority);
+ }
+
+ WSP.Octet.encode(data, priority);
+ },
};
/**
* Recommended-Retrieval-Mode-value = Manual
* Manual = <Octet 128>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.39
*/
@@ -846,16 +1148,74 @@ let ReplyChargingValue = {
decode: function decode(data) {
let value = WSP.Octet.decode(data);
if ((value >= 128) && (value <= 131)) {
return value;
}
throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An integer value within thr range 128..131.
+ */
+ encode: function encode(data, value) {
+ if ((value < 128) || (value > 131)) {
+ throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
+ }
+
+ WSP.Octet.encode(data, value);
+ },
+};
+
+/**
+ * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
+ *
+ * Response-text-value = Encoded-string-value
+ *
+ * When used in the M-Mbox-Delete.conf and M-Delete.conf PDUs:
+ *
+ * Response-text-Del-value = Value-length Status-count-value Response-text-value
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.49
+ */
+let ResponseText = {
+ /**
+ * @param data
+ * A wrapped object containing raw PDU data.
+ * @param options
+ * Extra context for decoding.
+ *
+ * @return An object containing a string-typed `text` attribute and a
+ * integer-typed `statusCount` one.
+ */
+ decode: function decode(data, options) {
+ let type = WSP.ensureHeader(options, "x-mms-message-type");
+
+ let result = {};
+ if ((type == MMS_PDU_TYPE_MBOX_DELETE_CONF)
+ || (type == MMS_PDU_TYPE_DELETE_CONF)) {
+ let length = WSP.ValueLength.decode(data);
+ let end = data.offset + length;
+
+ result.statusCount = WSP.IntegerValue.decode(data);
+ result.text = EncodedStringValue.decode(data);
+
+ if (data.offset != end) {
+ data.offset = end;
+ }
+ } else {
+ result.text = EncodedStringValue.decode(data);
+ }
+
+ return result;
+ },
};
/**
* Retrieve-status-value = Ok | Error-transient-failure |
* Error-transient-message-not-found |
* Error-transient-network-problem |
* Error-permanent-failure |
* Error-permanent-service-denied |
@@ -1068,82 +1428,81 @@ let PduHelper = {
debug("Failed to parse MMS message, error message: " + e.message);
return null;
}
return msg;
},
/**
- * Convert javascript Array to an nsIInputStream.
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param headers
+ * A dictionary object containing multiple name/value mapping.
+ * @param name
+ * Name of the header field to be encoded.
*/
- convertArrayToInputStream: function convertDataToInputStream(array) {
- let storageStream = Cc["@mozilla.org/storagestream;1"]
- .createInstance(Ci.nsIStorageStream);
- storageStream.init(4096, array.length, null);
+ encodeHeader: function encodeHeader(data, headers, name) {
+ let value = headers[name];
+ if (Array.isArray(value)) {
+ for (let i = 0; i < value.length; i++) {
+ HeaderField.encode(data, {name: name, value: value[i]}, headers);
+ }
+ } else {
+ HeaderField.encode(data, {name: name, value: value}, headers);
+ }
+ },
- let boStream = Cc["@mozilla.org/binaryoutputstream;1"]
- .createInstance(Ci.nsIBinaryOutputStream);
- boStream.setOutputStream(storageStream.getOutputStream(0));
- boStream.writeByteArray(array, array.length)
- boStream.close();
-
- return storageStream.newInputStream(0);
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param headers
+ * A dictionary object containing multiple name/value mapping.
+ */
+ encodeHeaderIfExists: function encodeHeaderIfExists(data, headers, name) {
+ // Header value could be zero or null.
+ if (headers[name] !== undefined) {
+ this.encodeHeader(data, headers, name);
+ }
},
/**
* @param data [optional]
* A wrapped object to store encoded raw data. Created if undefined.
* @param headers
* A dictionary object containing multiple name/value mapping.
*
* @return the passed data parameter or a created one.
*/
encodeHeaders: function encodeHeaders(data, headers) {
if (!data) {
data = {array: [], offset: 0};
}
- function encodeHeader(name) {
- HeaderField.encode(data, {name: name, value: headers[name]});
- }
-
- function encodeHeaderIfExists(name) {
- // Header value could be zero or null.
- if (headers[name] !== undefined) {
- encodeHeader(name);
- }
- }
-
// `In the encoding of the header fields, the order of the fields is not
// significant, except that X-Mms-Message-Type, X-Mms-Transaction-ID (when
// present) and X-Mms-MMS-Version MUST be at the beginning of the message
// headers, in that order, and if the PDU contains a message body the
// Content Type MUST be the last header field, followed by message body.`
// ~ OMA-TS-MMS_ENC-V1_3-20110913-A section 7
- encodeHeader("x-mms-message-type");
- encodeHeaderIfExists("x-mms-transaction-id");
- encodeHeaderIfExists("x-mms-mms-version");
+ this.encodeHeader(data, headers, "x-mms-message-type");
+ this.encodeHeaderIfExists(data, headers, "x-mms-transaction-id");
+ this.encodeHeaderIfExists(data, headers, "x-mms-mms-version");
for (let key in headers) {
if ((key == "x-mms-message-type")
|| (key == "x-mms-transaction-id")
|| (key == "x-mms-mms-version")
|| (key == "content-type")) {
continue;
}
- encodeHeader(key);
+ this.encodeHeader(data, headers, key);
}
- encodeHeaderIfExists("content-type");
-
- // Remove extra space consumed during encoding.
- while (data.array.length > data.offset) {
- data.array.pop();
- }
+ this.encodeHeaderIfExists(data, headers, "content-type");
return data;
},
/**
* @param multiStream
* An exsiting nsIMultiplexInputStream.
* @param msg
@@ -1158,18 +1517,25 @@ let PduHelper = {
}
try {
// Validity checks
let typeinfo = this.checkMandatoryFields(msg);
let data = this.encodeHeaders(null, msg.headers);
debug("Composed PDU Header: " + JSON.stringify(data.array));
- let headerStream = this.convertArrayToInputStream(data.array);
- multiStream.appendStream(headerStream);
+ WSP.PduHelper.appendArrayToMultiStream(multiStream, data.array, data.offset);
+
+ if (msg.content) {
+ WSP.PduHelper.appendArrayToMultiStream(multiStream, msg.content, msg.content.length);
+ } else if (msg.parts) {
+ WSP.PduHelper.composeMultiPart(multiStream, msg.parts);
+ } else if (typeinfo.hasContent) {
+ throw new WSP.CodeError("Missing message content");
+ }
return multiStream;
} catch (e) {
debug("Failed to compose MMS message, error message: " + e.message);
return null;
}
},
};
@@ -1179,39 +1545,54 @@ const MMS_PDU_TYPES = (function () {
function add(number, hasContent, mandatoryFields) {
pdus[number] = {
number: number,
hasContent: hasContent,
mandatoryFields: mandatoryFields,
};
}
+ add(MMS_PDU_TYPE_SEND_REQ, true, ["x-mms-message-type",
+ "x-mms-transaction-id",
+ "x-mms-mms-version",
+ "from",
+ "content-type"]);
+ add(MMS_PDU_TYPE_SEND_CONF, false, ["x-mms-message-type",
+ "x-mms-transaction-id",
+ "x-mms-mms-version",
+ "x-mms-response-status"]);
add(MMS_PDU_TYPE_NOTIFICATION_IND, false, ["x-mms-message-type",
"x-mms-transaction-id",
"x-mms-mms-version",
"x-mms-message-class",
"x-mms-message-size",
"x-mms-expiry",
"x-mms-content-location"]);
add(MMS_PDU_TYPE_RETRIEVE_CONF, true, ["x-mms-message-type",
"x-mms-mms-version",
"date",
"content-type"]);
add(MMS_PDU_TYPE_NOTIFYRESP_IND, false, ["x-mms-message-type",
"x-mms-transaction-id",
"x-mms-mms-version",
"x-mms-status"]);
+ add(MMS_PDU_TYPE_DELIVERY_IND, false, ["x-mms-message-type",
+ "x-mms-mms-version",
+ "message-id",
+ "to",
+ "date",
+ "x-mms-status"]);
return pdus;
})();
/**
* Header field names and assigned numbers.
*
- * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.4
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.4
*/
const MMS_HEADER_FIELDS = (function () {
let names = {};
function add(name, number, coder) {
let entry = {
name: name,
number: number,
coder: coder,
@@ -1220,48 +1601,48 @@ const MMS_HEADER_FIELDS = (function () {
}
add("bcc", 0x01, Address);
add("cc", 0x02, Address);
add("x-mms-content-location", 0x03, ContentLocationValue);
add("content-type", 0x04, WSP.ContentTypeValue);
add("date", 0x05, WSP.DateValue);
add("x-mms-delivery-report", 0x06, BooleanValue);
- //add("x-mms-delivery-time", 0x07);
+ add("x-mms-delivery-time", 0x07, ExpiryValue);
add("x-mms-expiry", 0x08, ExpiryValue);
add("from", 0x09, FromValue);
add("x-mms-message-class", 0x0A, MessageClassValue);
add("message-id", 0x0B, WSP.TextString);
add("x-mms-message-type", 0x0C, MessageTypeValue);
add("x-mms-mms-version", 0x0D, WSP.ShortInteger);
add("x-mms-message-size", 0x0E, WSP.LongInteger);
add("x-mms-priority", 0x0F, PriorityValue);
add("x-mms-read-report", 0x10, BooleanValue);
add("x-mms-report-allowed", 0x11, BooleanValue);
- //add("x-mms-response-status", 0x12);
- //add("x-mms-response-text", 0x13);
- //add("x-mms-sender-visibility", 0x14);
+ add("x-mms-response-status", 0x12, RetrieveStatusValue);
+ add("x-mms-response-text", 0x13, ResponseText);
+ add("x-mms-sender-visibility", 0x14, BooleanValue);
add("x-mms-status", 0x15, StatusValue);
add("subject", 0x16, EncodedStringValue);
add("to", 0x17, Address);
add("x-mms-transaction-id", 0x18, WSP.TextString);
add("x-mms-retrieve-status", 0x19, RetrieveStatusValue);
add("x-mms-retrieve-text", 0x1A, EncodedStringValue);
//add("x-mms-read-status", 0x1B);
add("x-mms-reply-charging", 0x1C, ReplyChargingValue);
add("x-mms-reply-charging-deadline", 0x1D, ExpiryValue);
add("x-mms-reply-charging-id", 0x1E, WSP.TextString);
add("x-mms-reply-charging-size", 0x1F, WSP.LongInteger);
add("x-mms-previously-sent-by", 0x20, PreviouslySentByValue);
add("x-mms-previously-sent-date", 0x21, PreviouslySentDateValue);
add("x-mms-store", 0x22, BooleanValue);
add("x-mms-mm-state", 0x23, MmStateValue);
add("x-mms-mm-flags", 0x24, MmFlagsValue);
- //add("x-mms-store-status", 0x25);
- //add("x-mms-store-status-text", 0x26);
+ add("x-mms-store-status", 0x25, RetrieveStatusValue);
+ add("x-mms-store-status-text", 0x26, EncodedStringValue);
add("x-mms-stored", 0x27, BooleanValue);
//add("x-mms-attributes", 0x28);
add("x-mms-totals", 0x29, BooleanValue);
//add("x-mms-mbox-totals", 0x2A);
add("x-mms-quotas", 0x2B, BooleanValue);
//add("x-mms-mbox-quotas", 0x2C);
add("x-mms-message-count", 0x2D, WSP.IntegerValue);
//add("content", 0x2E);
@@ -1294,16 +1675,17 @@ const MMS_WELL_KNOWN_PARAMS = (function
let entry = {
name: name,
number: number,
coder: coder,
};
params[name] = params[number] = entry;
}
+ // Encoding Version: 1.2
add("type", 0x02, WSP.TypeValue);
return params;
})();
let debug;
if (DEBUG) {
debug = function (s) {
@@ -1333,15 +1715,16 @@ const EXPORTED_SYMBOLS = ALL_CONST_SYMBO
"PreviouslySentDateValue",
"MessageClassValue",
"MessageTypeValue",
"MmFlagsValue",
"MmStateValue",
"PriorityValue",
"RecommendedRetrievalModeValue",
"ReplyChargingValue",
+ "ResponseText",
"RetrieveStatusValue",
"StatusValue",
// Parser
"PduHelper",
]);
--- a/dom/mms/src/ril/MmsService.js
+++ b/dom/mms/src/ril/MmsService.js
@@ -36,16 +36,20 @@ const CONFIG_SEND_REPORT_NEVER = 0
const CONFIG_SEND_REPORT_DEFAULT_NO = 1;
const CONFIG_SEND_REPORT_DEFAULT_YES = 2;
const CONFIG_SEND_REPORT_ALWAYS = 3;
XPCOMUtils.defineLazyServiceGetter(this, "gpps",
"@mozilla.org/network/protocol-proxy-service;1",
"nsIProtocolProxyService");
+XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
+ "@mozilla.org/uuid-generator;1",
+ "nsIUUIDGenerator");
+
XPCOMUtils.defineLazyGetter(this, "MMS", function () {
let MMS = {};
Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
return MMS;
});
/**
* MmsService
@@ -223,16 +227,94 @@ MmsService.prototype = {
// Optional fields
headers["x-mms-report-allowed"] = ra;
let istream = MMS.PduHelper.compose(null, {headers: headers});
this.sendMmsRequest("POST", this.MMSC, istream);
},
/**
+ * Send M-Send.req to MMSC
+ */
+ sendSendRequest: function sendSendRequest(msg, callback) {
+ msg.headers["x-mms-message-type"] = MMS.MMS_PDU_TYPE_SEND_REQ;
+ if (!msg.headers["x-mms-transaction-id"]) {
+ // Create an unique transaction id
+ let tid = gUUIDGenerator.generateUUID().toString();
+ msg.headers["x-mms-transaction-id"] = tid;
+ }
+ msg.headers["x-mms-mms-version"] = MMS.MMS_VERSION;
+
+ // Let MMS Proxy Relay insert from address automatically for us
+ msg.headers["from"] = null;
+
+ msg.headers["date"] = new Date();
+ msg.headers["x-mms-message-class"] = "personal";
+ msg.headers["x-mms-expiry"] = 7 * 24 * 60 * 60;
+ msg.headers["x-mms-priority"] = 129;
+ msg.headers["x-mms-read-report"] = true;
+ msg.headers["x-mms-delivery-report"] = true;
+
+ let messageSize = 0;
+
+ if (msg.content) {
+ messageSize = msg.content.length;
+ } else if (msg.parts) {
+ for (let i = 0; i < msg.parts.length; i++) {
+ messageSize += msg.parts[i].content.length;
+ }
+
+ let contentType = {
+ params: {
+ // `The type parameter must be specified and its value is the MIME
+ // media type of the "root" body part.` ~ RFC 2387 clause 3.1
+ type: msg.parts[0].headers["content-type"].media,
+ },
+ };
+
+ // `The Content-Type in M-Send.req and M-Retrieve.conf SHALL be
+ // application/vnd.wap.multipart.mixed when there is no presentation, and
+ // application/vnd.wap.multipart.related SHALL be used when there is SMIL
+ // presentation available.` ~ OMA-TS-MMS_CONF-V1_3-20110913-A clause 10.2.1
+ if (contentType.params.type === "application/smil") {
+ contentType.media = "application/vnd.wap.multipart.related";
+
+ // `The start parameter, if given, is the content-ID of the compound
+ // object's "root".` ~ RFC 2387 clause 3.2
+ contentType.params.start = msg.parts[0].headers["content-id"];
+ } else {
+ contentType.media = "application/vnd.wap.multipart.mixed";
+ }
+
+ // Assign to Content-Type
+ msg.headers["content-type"] = contentType;
+ }
+
+ // Assign to X-Mms-Message-Size
+ msg.headers["x-mms-message-size"] = messageSize;
+
+ debug("msg: " + JSON.stringify(msg));
+
+ let istream = MMS.PduHelper.compose(null, msg);
+ if (!istream) {
+ debug("sendSendRequest: failed to compose M-Send.ind PDU");
+ callback(MMS.MMS_PDU_ERROR_PERMANENT_FAILURE, null);
+ return;
+ }
+
+ this.sendMmsRequest("POST", this.MMSC, istream, (function (status, data) {
+ if (!data) {
+ callback(MMS.MMS_PDU_ERROR_PERMANENT_FAILURE, null);
+ } else if (!this.parseStreamAndDispatch(data, {msg: msg, callback: callback})) {
+ callback(MMS.MMS_PDU_RESPONSE_ERROR_UNSUPPORTED_MESSAGE, null);
+ }
+ }).bind(this));
+ },
+
+ /**
* @param file
* A nsIFile object indicating where to save the data.
* @param data
* An array of raw octets.
* @param callback
* Callback function when I/O is done.
*
* @return An nsIRequest representing the copy operation returned by
@@ -312,31 +394,65 @@ MmsService.prototype = {
parseStreamAndDispatch: function parseStreamAndDispatch(data, options) {
let msg = MMS.PduHelper.parse(data, null);
if (!msg) {
return false;
}
debug("parseStreamAndDispatch: msg = " + JSON.stringify(msg));
switch (msg.type) {
+ case MMS.MMS_PDU_TYPE_SEND_CONF:
+ this.handleSendConfirmation(msg, options);
+ break;
case MMS.MMS_PDU_TYPE_NOTIFICATION_IND:
this.handleNotificationIndication(msg, options);
break;
case MMS.MMS_PDU_TYPE_RETRIEVE_CONF:
this.handleRetrieveConfirmation(msg, options);
break;
+ case MMS.MMS_PDU_TYPE_DELIVERY_IND:
+ this.handleDeliveryIndication(msg, options);
+ break;
default:
debug("Unsupported X-MMS-Message-Type: " + msg.type);
return false;
}
return true;
},
/**
+ * Handle incoming M-Send.conf PDU.
+ *
+ * @param msg
+ * The M-Send.conf message object.
+ */
+ handleSendConfirmation: function handleSendConfirmation(msg, options) {
+ let status = msg.headers["x-mms-response-status"];
+ if (status == null) {
+ return;
+ }
+
+ if (status == MMS.MMS_PDU_ERROR_OK) {
+ // `This ID SHALL always be present after the MMS Proxy-Relay accepted
+ // the corresponding M-Send.req PDU. The ID enables a MMS Client to match
+ // delivery reports or read-report PDUs with previously sent MM.`
+ let messageId = msg.headers["message-id"];
+ options.msg.headers["message-id"] = messageId;
+ } else if ((status >= MMS.MMS_PDU_ERROR_TRANSIENT_FAILURE)
+ && (status < MMS.MMS_PDU_ERROR_PERMANENT_FAILURE)) {
+ return;
+ }
+
+ if (options.callback) {
+ options.callback(status, msg);
+ }
+ },
+
+ /**
* Handle incoming M-Notification.ind PDU.
*
* @param msg
* The MMS message object.
*/
handleNotificationIndication: function handleNotificationIndication(msg) {
function callback(status, retr) {
let tid = msg.headers["x-mms-transaction-id"];
@@ -392,16 +508,24 @@ MmsService.prototype = {
callbackIfValid(status, msg);
return;
}
this.saveMessageContent(msg, callbackIfValid.bind(null, MMS.MMS_PDU_ERROR_OK));
},
/**
+ * Handle incoming M-Delivery.ind PDU.
+ */
+ handleDeliveryIndication: function handleDeliveryIndication(msg) {
+ let messageId = msg.headers["message-id"];
+ debug("handleDeliveryIndication: got delivery report for " + messageId);
+ },
+
+ /**
* Update proxyInfo & MMSC from preferences.
*
* @param enabled
* Enable or disable MMS proxy.
*/
updateProxyInfo: function updateProxyInfo(enabled) {
try {
if (enabled) {
--- a/dom/mms/src/ril/WspPduHelper.jsm
+++ b/dom/mms/src/ril/WspPduHelper.jsm
@@ -284,16 +284,28 @@ let Octet = {
encode: function encode(data, octet) {
if (data.offset >= data.array.length) {
data.array.push(octet);
data.offset++;
} else {
data.array[data.offset++] = octet;
}
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param octet
+ * An octet array object.
+ */
+ encodeMultiple: function encodeMultiple(data, array) {
+ for (let i = 0; i < array.length; i++) {
+ this.encode(data, array[i]);
+ }
+ },
};
/**
* TEXT = <any OCTET except CTLs, but including LWS>
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
* LWS = [CRLF] 1*(SP|HT)
* CRLF = CR LF
* CR = <US-ASCII CR, carriage return (13)>
@@ -654,16 +666,27 @@ let QuotedString = {
decode: function decode(data) {
let value = Octet.decode(data);
if (value != 34) {
throw new CodeError("Quoted-string: not quote " + value);
}
return NullTerminatedTexts.decode(data);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param str
+ * A String to be encoded.
+ */
+ encode: function encode(data, str) {
+ Octet.encode(data, 34);
+ NullTerminatedTexts.encode(data, str);
+ },
};
/**
* Integers in range 0-127 shall be encoded as a one octet value with the
* most significant bit set to one (1xxx xxxx) and with the value in the
* remaining least significant bits.
*
* Short-integer = OCTET
@@ -752,16 +775,52 @@ let LongInteger = {
decode: function decode(data) {
let length = Octet.decode(data);
if ((length < 1) || (length > 30)) {
throw new CodeError("Long-integer: invalid length " + length);
}
return this.decodeMultiOctetInteger(data, length);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param numOrArray
+ * An octet array of less-equal than 30 elements or an integer
+ * greater-equal than 128.
+ */
+ encode: function encode(data, numOrArray) {
+ if (typeof numOrArray === "number") {
+ let num = numOrArray;
+ if (num >= 0x1000000000000) {
+ throw new CodeError("Long-integer: number too large " + num);
+ }
+
+ let stack = [];
+ do {
+ stack.push(Math.floor(num % 256));
+ num = Math.floor(num / 256);
+ } while (num);
+
+ Octet.encode(data, stack.length);
+ while (stack.length) {
+ Octet.encode(data, stack.pop());
+ }
+ return;
+ }
+
+ let array = numOrArray;
+ if ((array.length < 1) || (array.length > 30)) {
+ throw new CodeError("Long-integer: invalid length " + array.length);
+ }
+
+ Octet.encode(data, array.length);
+ Octet.encodeMultiple(data, array);
+ },
};
/**
* @see WAP-230-WSP-20010705-a clause 8.4.2.1
*/
let UintVar = {
/**
* @param data
@@ -774,16 +833,40 @@ let UintVar = {
let result = value & 0x7F;
while (value & 0x80) {
value = Octet.decode(data);
result = result * 128 + (value & 0x7F);
}
return result;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An integer value.
+ */
+ encode: function encode(data, value) {
+ if (value < 0) {
+ throw new CodeError("UintVar: invalid value " + value);
+ }
+
+ let stack = [];
+ while (value >= 128) {
+ stack.push(Math.floor(value % 128));
+ value = Math.floor(value / 128);
+ }
+
+ while (stack.length) {
+ Octet.encode(data, value | 0x80);
+ value = stack.pop();
+ }
+ Octet.encode(data, value);
+ },
};
/**
* This encoding is used for token values, which have no well-known binary
* encoding, or when the assigned number of the well-known encoding is small
* enough to fit into Short-Integer.
*
* Constrained-encoding = Extension-Media | Short-integer
@@ -796,16 +879,30 @@ let ConstrainedEncoding = {
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decode integer value or string.
*/
decode: function decode(data) {
return decodeAlternatives(data, null, NullTerminatedTexts, ShortInteger);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An integer or a string value.
+ */
+ encode: function encode(data, value) {
+ if (typeof value == "number") {
+ ShortInteger.encode(data, value);
+ } else {
+ NullTerminatedTexts.encode(data, value);
+ }
+ },
};
/**
* Value-length = Short-length | (Length-quote Length)
* Short-length = <Any octet 0-30>
* Length-quote = <Octet 31>
* Length = Uintvar-integer
*
@@ -827,16 +924,30 @@ let ValueLength = {
}
if (value == 31) {
return UintVar.decode(data);
}
throw new CodeError("Value-length: invalid value " + value);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ */
+ encode: function encode(data, value) {
+ if (value <= 30) {
+ Octet.encode(data, value);
+ } else {
+ Octet.encode(data, 31);
+ UintVar.encode(data, value);
+ }
+ },
};
/**
* No-value = <Octet 0>
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.3
*/
let NoValue = {
@@ -845,16 +956,29 @@ let NoValue = {
* A wrapped object containing raw PDU data.
*
* @return Always returns null.
*/
decode: function decode(data) {
Octet.decodeEqualTo(data, 0);
return null;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * A null or undefined value.
+ */
+ encode: function encode(data, value) {
+ if (value != null) {
+ throw new CodeError("No-value: invalid value " + value);
+ }
+ Octet.encode(data, 0);
+ },
};
/**
* Text-value = No-value | Token-text | Quoted-string
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.3
*/
let TextValue = {
@@ -862,16 +986,26 @@ let TextValue = {
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decoded string or null for No-value.
*/
decode: function decode(data) {
return decodeAlternatives(data, null, NoValue, TokenText, QuotedString);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param text
+ * A null or undefined or text string.
+ */
+ encode: function encode(data, text) {
+ encodeAlternatives(data, text, null, NoValue, TokenText, QuotedString);
+ },
};
/**
* Integer-Value = Short-integer | Long-integer
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.3
*/
let IntegerValue = {
@@ -879,16 +1013,32 @@ let IntegerValue = {
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decoded integer value or array of octets.
*/
decode: function decode(data) {
return decodeAlternatives(data, null, ShortInteger, LongInteger);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An integer value or an octet array of less-equal than 31 elements.
+ */
+ encode: function encode(data, value) {
+ if (typeof value === "number") {
+ encodeAlternatives(data, value, null, ShortInteger, LongInteger);
+ } else if (Array.isArray(value) || (value instanceof Uint8Array)) {
+ LongInteger.encode(data, value);
+ } else {
+ throw new CodeError("Integer-Value: invalid value type");
+ }
+ },
};
/**
* The encoding of dates shall be done in number of seconds from
* 1970-01-01, 00:00:00 GMT.
*
* Date-value = Long-integer
*
@@ -910,16 +1060,31 @@ let DateValue = {
seconds = 0;
for (let i = 0; i < numOrArray.length; i++) {
seconds = seconds * 256 + numOrArray[i];
}
}
return new Date(seconds * 1000);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param date
+ * A Date object.
+ */
+ encode: function encode(data, date) {
+ let seconds = date.getTime() / 1000;
+ if (seconds < 0) {
+ throw new CodeError("Date-value: negative seconds " + seconds);
+ }
+
+ LongInteger.encode(data, seconds);
+ },
};
/**
* Delta-seconds-value = Integer-value
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.3
*/
let DeltaSecondsValue = IntegerValue;
@@ -949,16 +1114,37 @@ let QValue = {
}
if (value <= 1099) {
return (value - 100) / 1000.0;
}
}
throw new CodeError("Q-value: invalid value " + value);
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An integer within the range 1..1099.
+ */
+ encode: function encode(data, value) {
+ if ((value < 0) || (value >= 1)) {
+ throw new CodeError("Q-value: invalid value " + value);
+ }
+
+ value *= 1000;
+ if ((value % 10) == 0) {
+ // Two digits only.
+ UintVar.encode(data, Math.floor(value / 10 + 1));
+ } else {
+ // Three digits.
+ UintVar.encode(data, Math.floor(value + 100));
+ }
+ },
};
/**
* The three most significant bits of the Short-integer value are interpreted
* to encode a major version number in the range 1-7, and the four least
* significant bits contain a minor version number in the range 0-14. If
* there is only a major version number, this is encoded by placing the value
* 15 in the four least significant bits.
@@ -1002,16 +1188,30 @@ let VersionValue = {
if (minor > 14) {
throw new CodeError("Version-value: invalid minor " + minor);
}
}
}
return major << 4 | minor;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param version
+ * A binary encoded version number.
+ */
+ encode: function encode(data, version) {
+ if ((version < 0x10) || (version >= 0x80)) {
+ throw new CodeError("Version-value: invalid version " + version);
+ }
+
+ ShortInteger.encode(data, version);
+ },
};
/**
* URI value should be encoded per [RFC2616], but service user may use a
* different format.
*
* Uri-value = Text-string
*
@@ -1062,16 +1262,31 @@ let TypeValue = {
let entry = WSP_WELL_KNOWN_CONTENT_TYPES[number];
if (!entry) {
throw new NotWellKnownEncodingError(
"Constrained-media: not well known media " + number);
}
return entry.type;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param type
+ * A content type string.
+ */
+ encode: function encode(data, type) {
+ let entry = WSP_WELL_KNOWN_CONTENT_TYPES[type.toLowerCase()];
+ if (entry) {
+ ShortInteger.encode(data, entry.number);
+ } else {
+ NullTerminatedTexts.encode(data, type);
+ }
+ },
};
/**
* Parameter = Typed-parameter | Untyped-parameter
*
* For Typed-parameters, the actual expected type of the value is implied by
* the well-known parameter. In addition to the expected type, there may be no
* value. If the value cannot be encoded using expected type, it shall be
@@ -1215,16 +1430,73 @@ let Parameter = {
params = {};
}
params[param.name] = param.value;
}
}
return params;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param param
+ * An object containing `name` and `value` properties.
+ */
+ encodeTypedParameter: function decodeTypedParameter(data, param) {
+ let entry = WSP_WELL_KNOWN_PARAMS[param.name.toLowerCase()];
+ if (!entry) {
+ throw new NotWellKnownEncodingError(
+ "Typed-parameter: not well known parameter " + param.name);
+ }
+
+ IntegerValue.encode(data, entry.number);
+ encodeAlternatives(data, param.value, null,
+ entry.coder, TextValue, TextString);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param param
+ * An object containing `name` and `value` properties.
+ */
+ encodeUntypedParameter: function encodeUntypedParameter(data, param) {
+ TokenText.encode(data, param.name);
+ encodeAlternatives(data, param.value, null, IntegerValue, TextValue);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param param
+ * An array of parameter objects.
+ */
+ encodeMultiple: function encodeMultiple(data, params) {
+ for (let name in params) {
+ this.encode(data, {name: name, value: params[name]});
+ }
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param param
+ * An object containing `name` and `value` properties.
+ */
+ encode: function encode(data, param) {
+ let begin = data.offset;
+ try {
+ this.encodeTypedParameter(data, param);
+ } catch (e) {
+ data.offset = begin;
+ this.encodeUntypedParameter(data, param);
+ }
+ },
};
/**
* Header = Message-header | Shift-sequence
* Message-header = Well-known-header | Application-header
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.6
*/
@@ -1250,16 +1522,32 @@ let Header = {
* in case of a failed parsing. The `name` property must be a string,
* but the `value` property can be many different types depending on
* `name`.
*/
decode: function decode(data) {
// TODO: support header code page shift-sequence
return this.decodeMessageHeader(data);
},
+
+ encodeMessageHeader: function encodeMessageHeader(data, header) {
+ encodeAlternatives(data, header, null, WellKnownHeader, ApplicationHeader);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param header
+ * An object containing two attributes: a string-typed `name` and a
+ * `value` of arbitrary type.
+ */
+ encode: function encode(data, header) {
+ // TODO: support header code page shift-sequence
+ this.encodeMessageHeader(data, header);
+ },
};
/**
* Well-known-header = Well-known-field-name Wap-value
* Well-known-field-name = Short-integer
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.6
*/
@@ -1298,16 +1586,34 @@ let WellKnownHeader = {
return null;
}
return {
name: entry.name,
value: value,
};
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param header
+ * An object containing two attributes: a string-typed `name` and a
+ * `value` of arbitrary type.
+ */
+ encode: function encode(data, header) {
+ let entry = WSP_HEADER_FIELDS[header.name.toLowerCase()];
+ if (!entry) {
+ throw new NotWellKnownEncodingError(
+ "Well-known-header: not well known header " + header.name);
+ }
+
+ ShortInteger.encode(data, entry.number);
+ encodeAlternatives(data, header.value, null, entry.coder, TextValue);
+ },
};
/**
* Application-header = Token-text Application-specific-value
* Application-specific-value = Text-string
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.6
*/
@@ -1390,16 +1696,31 @@ let FieldName = {
let entry = WSP_HEADER_FIELDS[number];
if (!entry) {
throw new NotWellKnownEncodingError(
"Field-name: not well known encoding " + number);
}
return entry.name;
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param name
+ * A field name string.
+ */
+ encode: function encode(data, name) {
+ let entry = WSP_HEADER_FIELDS[name.toLowerCase()];
+ if (entry) {
+ ShortInteger.encode(data, entry.number);
+ } else {
+ TokenText.encode(data, name);
+ }
+ },
};
/**
* Accept-charset-value = Constrained-charset | Accept-charset-general-form
* Constrained-charset = Any-charset | Constrained-encoding
* Any-charset = <Octet 128>
* Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
*
@@ -1493,16 +1814,31 @@ let AcceptCharsetValue = {
let begin = data.offset;
try {
return this.decodeConstrainedCharset(data);
} catch (e) {
data.offset = begin;
return this.decodeAcceptCharsetGeneralForm(data);
}
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object with a string property `charset`.
+ */
+ encodeAnyCharset: function encodeAnyCharset(data, value) {
+ if (!value || !value.charset || (value.charset === "*")) {
+ Octet.encode(data, 128);
+ return;
+ }
+
+ throw new CodeError("Any-charset: invalid value " + value);
+ },
};
/**
* Well-known-charset = Any-charset | Integer-value
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.8
*/
let WellKnownCharset = {
@@ -1535,16 +1871,38 @@ let WellKnownCharset = {
let entry = WSP_WELL_KNOWN_CHARSETS[charset];
if (!entry) {
throw new NotWellKnownEncodingError(
"Well-known-charset: not well known charset " + charset);
}
return {charset: entry.name};
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ */
+ encode: function encode(data, value) {
+ let begin = data.offset;
+ try {
+ AcceptCharsetValue.encodeAnyCharset(data, value);
+ return;
+ } catch (e) {}
+
+ data.offset = begin;
+ let entry = WSP_WELL_KNOWN_CHARSETS[value.charset.toLowerCase()];
+ if (!entry) {
+ throw new NotWellKnownEncodingError(
+ "Well-known-charset: not well known charset " + value.charset);
+ }
+
+ IntegerValue.encode(data, entry.number);
+ },
};
/**
* The short form of the Content-type-value MUST only be used when the
* well-known media is in the range of 0-127 or a text string. In all other
* cases the general form MUST be used.
*
* Content-type-value = Constrained-media | Content-general-form
@@ -1665,16 +2023,83 @@ let ContentTypeValue = {
try {
return this.decodeConstrainedMedia(data);
} catch (e) {
data.offset = begin;
return this.decodeContentGeneralForm(data);
}
},
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object containing `media` and `params` properties.
+ */
+ encodeConstrainedMedia: function encodeConstrainedMedia(data, value) {
+ if (value.params) {
+ throw new CodeError("Constrained-media: should use general form instread");
+ }
+
+ TypeValue.encode(data, value.media);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object containing `media` and `params` properties.
+ */
+ encodeMediaType: function encodeMediaType(data, value) {
+ let entry = WSP_WELL_KNOWN_CONTENT_TYPES[value.media.toLowerCase()];
+ if (entry) {
+ IntegerValue.encode(data, entry.number);
+ } else {
+ NullTerminatedTexts.encode(data, value.media);
+ }
+
+ Parameter.encodeMultiple(data, value.params);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object containing `media` and `params` properties.
+ */
+ encodeContentGeneralForm: function encodeContentGeneralForm(data, value) {
+ let begin = data.offset;
+ this.encodeMediaType(data, value);
+
+ // Calculate how much octets will be written and seek back.
+ // TODO: use memmove, see bug 730873
+ let len = data.offset - begin;
+ data.offset = begin;
+
+ ValueLength.encode(data, len);
+ this.encodeMediaType(data, value);
+ },
+
+ /**
+ * @param data
+ * A wrapped object to store encoded raw data.
+ * @param value
+ * An object containing `media` and `params` properties.
+ */
+ encode: function encode(data, value) {
+ let begin = data.offset;
+
+ try {
+ this.encodeConstrainedMedia(data, value);
+ } catch (e) {
+ data.offset = begin;
+ this.encodeContentGeneralForm(data, value);
+ }
+ },
};
/**
* Application-id-value = Uri-value | App-assigned-code
* App-assigned-code = Integer-value
*
* @see WAP-230-WSP-20010705-a clause 8.4.2.54
*/
@@ -1864,16 +2289,95 @@ let PduHelper = {
}
} catch (e) {
debug("Parse error. Message: " + e.message);
msg = null;
}
return msg;
},
+
+ /**
+ * @param multiStream
+ * An exsiting nsIMultiplexInputStream.
+ * @param array
+ * An octet array.
+ * @param length
+ * Max number of octets to be coverted into an input stream.
+ */
+ appendArrayToMultiStream: function appendArrayToMultiStream(multiStream, array, length) {
+ let storageStream = Cc["@mozilla.org/storagestream;1"]
+ .createInstance(Ci.nsIStorageStream);
+ storageStream.init(4096, length, null);
+
+ let boStream = Cc["@mozilla.org/binaryoutputstream;1"]
+ .createInstance(Ci.nsIBinaryOutputStream);
+ boStream.setOutputStream(storageStream.getOutputStream(0));
+ boStream.writeByteArray(array, length);
+ boStream.close();
+
+ multiStream.appendStream(storageStream.newInputStream(0));
+ },
+
+ /**
+ * @param multiStream
+ * An exsiting nsIMultiplexInputStream.
+ * @param parts
+ * An array of objects representing multipart entries.
+ *
+ * @see WAP-230-WSP-20010705-a section 8.5
+ */
+ composeMultiPart: function composeMultiPart(multiStream, parts) {
+ // Encode multipart header
+ {
+ let data = {array: [], offset: 0};
+ UintVar.encode(data, parts.length);
+ debug("Encoded multipart header: " + JSON.stringify(data.array));
+ this.appendArrayToMultiStream(multiStream, data.array, data.offset);
+ }
+
+ // Encode each part
+ for (let i = 0; i < parts.length; i++) {
+ let part = parts[i];
+ let data = {array: [], offset: 0};
+
+ // Encode Content-Type
+ let contentType = part.headers["content-type"];
+ ContentTypeValue.encode(data, contentType);
+
+ // Encode other headers
+ if (Object.keys(part).length > 1) {
+ // Remove Content-Type temporarily
+ delete part.headers["content-type"];
+
+ for (let name in part.headers) {
+ Header.encode(data, {name: name, value: part.headers[name]});
+ }
+
+ // Restore Content-Type back
+ part.headers["content-type"] = contentType;
+ }
+
+ // Encode headersLen, DataLen
+ let headersLen = data.offset;
+ UintVar.encode(data, headersLen);
+ UintVar.encode(data, part.content.length);
+
+ // Move them to the beginning of encoded octet array.
+ let slice1 = data.array.slice(headersLen);
+ let slice2 = data.array.slice(0, headersLen);
+ data.array = slice1.concat(slice2);
+ debug("Encoded per-part header: " + JSON.stringify(data.array));
+
+ // Append per-part header
+ this.appendArrayToMultiStream(multiStream, data.array, data.offset);
+ // Append part content
+ this.appendArrayToMultiStream(multiStream, part.content, part.content.length);
+ }
+ },
};
// WSP Header Field Name Assignments
// Note: Items commented out are either deprecated or not implemented.
// Deprecated items should only be supported for backward compatibility
// purpose.
// @see WAP-230-WSP-20010705-a Appendix A. Assigned Numbers.
const WSP_HEADER_FIELDS = (function () {
@@ -1882,16 +2386,17 @@ const WSP_HEADER_FIELDS = (function () {
let entry = {
name: name,
number: number,
coder: coder,
};
names[name] = names[number] = entry;
}
+ // Encoding Version: 1.1
//add("accept", 0x00);
//add("accept-charset", 0x01); Deprecated
//add("accept-encoding", 0x02); Deprecated
//add("accept-language", 0x03);
//add("accept-ranges", 0x04);
add("age", 0x05, DeltaSecondsValue);
//add("allow", 0x06);
//add("authorization", 0x07);
@@ -1929,37 +2434,43 @@ const WSP_HEADER_FIELDS = (function () {
//add("transfer-encoding", 0x27);
add("upgrade", 0x28, TextString);
add("user-agent", 0x29, TextString);
//add("vary", 0x2A);
add("via", 0x2B, TextString);
//add("warning", 0x2C);
//add("www-authenticate", 0x2D);
//add("content-disposition", 0x2E); Deprecated
+
+ // Encoding Version: 1.2
add("x-wap-application-id", 0x2F, ApplicationIdValue);
add("x-wap-content-uri", 0x30, UriValue);
add("x-wap-initiator-uri", 0x31, UriValue);
//add("accept-application", 0x32);
add("bearer-indication", 0x33, IntegerValue);
add("push-flag", 0x34, ShortInteger);
add("profile", 0x35, UriValue);
//add("profile-diff", 0x36);
//add("profile-warning", 0x37); Deprecated
+
+ // Encoding Version: 1.3
//add("expect", 0x38);
//add("te", 0x39);
//add("trailer", 0x3A);
add("accept-charset", 0x3B, AcceptCharsetValue);
//add("accept-encoding", 0x3C);
//add("cache-control", 0x3D); Deprecated
//add("content-range", 0x3E);
add("x-wap-tod", 0x3F, DateValue);
add("content-id", 0x40, QuotedString);
//add("set-cookie", 0x41);
//add("cookie", 0x42);
//add("encoding-version", 0x43);
+
+ // Encoding Version: 1.4
//add("profile-warning", 0x44);
//add("content-disposition", 0x45);
//add("x-wap-security", 0x46);
//add("cache-control", 0x47);
return names;
})();
@@ -1972,17 +2483,23 @@ const WSP_WELL_KNOWN_CONTENT_TYPES = (fu
let entry = {
type: type,
number: number,
};
types[type] = types[number] = entry;
}
// Well Known Values
+ // Encoding Version: 1.1
+ add("application/vnd.wap.multipart.mixed", 0x23);
+
+ // Encoding Version: 1.2
add("application/vnd.wap.multipart.related", 0x33);
+
+ // Encoding Version: 1.4
add("application/vnd.wap.mms-message", 0x3E);
return types;
})();
// WSP Well-Known Parameter Assignments
// Note: Items commented out are either deprecated or not implemented.
// Deprecated items should not be used.
@@ -1994,41 +2511,48 @@ const WSP_WELL_KNOWN_PARAMS = (function
let entry = {
name: name,
number: number,
coder: coder,
};
params[name] = params[number] = entry;
}
+ // Encoding Version: 1.1
add("q", 0x00, QValue);
add("charset", 0x01, WellKnownCharset);
add("level", 0x02, VersionValue);
add("type", 0x03, IntegerValue);
add("name", 0x05, TextValue); // Deprecated, but used in some carriers, eg. Hinet.
//add("filename", 0x06); Deprecated
add("differences", 0x07, FieldName);
add("padding", 0x08, ShortInteger);
+
+ // Encoding Version: 1.2
add("type", 0x09, TypeValue);
add("start", 0x0A, TextValue); // Deprecated, but used in some carriers, eg. T-Mobile.
//add("start-info", 0x0B); Deprecated
+
+ // Encoding Version: 1.3
//add("comment", 0x0C); Deprecated
//add("domain", 0x0D); Deprecated
add("max-age", 0x0E, DeltaSecondsValue);
//add("path", 0x0F); Deprecated
add("secure", 0x10, NoValue);
+
+ // Encoding Version: 1.4
add("sec", 0x11, ShortInteger);
add("mac", 0x12, TextValue);
add("creation-date", 0x13, DateValue);
add("modification-date", 0x14, DateValue);
add("read-date", 0x15, DateValue);
add("size", 0x16, IntegerValue);
- add("name", 0x17, TextValue);
+ //add("name", 0x17, TextValue); // Not supported in some carriers, eg. Hinet.
add("filename", 0x18, TextValue);
- add("start", 0x19, TextValue);
+ //add("start", 0x19, TextValue); // Not supported in some carriers, eg. Hinet.
add("start-info", 0x1A, TextValue);
add("comment", 0x1B, TextValue);
add("domain", 0x1C, TextValue);
add("path", 0x1D, TextValue);
return params;
})();
--- a/dom/mms/src/ril/mms_consts.js
+++ b/dom/mms/src/ril/mms_consts.js
@@ -33,24 +33,61 @@ const MMS_PDU_TYPE_CANCEL_CONF = 151;
// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.34
const MMS_VERSION = (0x01 << 4) | 0x03;
// Common Status Values
const MMS_PDU_ERROR_OK = 128;
const MMS_PDU_ERROR_TRANSIENT_FAILURE = 192;
const MMS_PDU_ERROR_PERMANENT_FAILURE = 224;
+// X-Mms-Response-Status values
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.48
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 28, 29, 30
+//const MMS_PDU_RESPONSE_ERROR_UNSPECIFIED = 129; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_SERVICE_DENIED = 130; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_MESSAGE_FORMAT_CORRUPT = 131; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_SENDING_ADDRESS_UNRESOLVED = 132; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_MESSAGE_NOT_FOUND = 133; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_NETWORK_PROBLEM = 134; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_CONTENT_NOT_ACCEPTED = 135; (obsolete)
+const MMS_PDU_RESPONSE_ERROR_UNSUPPORTED_MESSAGE = 136;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_SENDING_ADDRESS_UNRESOLVED = 193;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 194;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_NETWORK_PROBLEM = 195;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_PARTIAL_SUCCESS = 196;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_SERVICE_DENIED = 225;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 226;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED = 227;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 228;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED = 229;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET = 230;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 231;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED = 232;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED = 233;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED = 234;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_LACK_OF_PREPAID = 235;
+
// X-Mms-Retrieve-Status values
// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.50
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 31
const MMS_PDU_RETRIEVE_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 193;
const MMS_PDU_RETRIEVE_ERROR_TRANSIENT_NETWORK_PROBLEM = 194;
const MMS_PDU_RETRIEVE_ERROR_PERMANENT_SERVICE_DENIED = 225;
const MMS_PDU_RETRIEVE_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 226;
const MMS_PDU_RETRIEVE_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 227;
+// X-Mms-Store-Status values
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.58
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 35
+const MMS_PDU_STORE_ERROR_TRANSIENT_NETWORK_PROBLEM = 193;
+const MMS_PDU_STORE_ERROR_PERMANENT_SERVICE_DENIED = 225;
+const MMS_PDU_STORE_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 226;
+const MMS_PDU_STORE_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 227;
+const MMS_PDU_STORE_ERROR_PERMANENT_MMBOX_FULL = 228;
+
// X-Mms-Status values
// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.54
const MMS_PDU_STATUS_EXPIRED = 128;
const MMS_PDU_STATUS_RETRIEVED = 129;
const MMS_PDU_STATUS_REJECTED = 130;
const MMS_PDU_STATUS_DEFERRED = 131;
const MMS_PDU_STATUS_UNRECOGNISED = 132;
const MMS_PDU_STATUS_INDETERMINATE = 133;
--- a/dom/mms/tests/test_mms_pdu_helper.js
+++ b/dom/mms/tests/test_mms_pdu_helper.js
@@ -66,19 +66,58 @@ add_test(function test_Address_decode()
{address: "+123", type: "num"});
wsp_decode_test(MMS.Address, strToCharCodeArray("*123"),
{address: "*123", type: "num"});
wsp_decode_test(MMS.Address, strToCharCodeArray("#123"),
{address: "#123", type: "num"});
// Test for alphanum-shortcode
wsp_decode_test(MMS.Address, strToCharCodeArray("H0wD0Y0uTurnTh1s0n"),
{address: "H0wD0Y0uTurnTh1s0n", type: "alphanum"});
- // Test for other unknown typed sequence
+ // Test for email address
wsp_decode_test(MMS.Address, strToCharCodeArray("Joe User <joe@user.org>"),
- {address: "Joe User <joe@user.org>", type: "unknown"});
+ {address: "Joe User <joe@user.org>", type: "email"});
+ // Test for invalid address
+ wsp_decode_test(MMS.Address, strToCharCodeArray("@@@@@"),
+ null, "CodeError");
+
+ run_next_test();
+});
+
+//// Address.encode ////
+
+add_test(function test_Address_encode() {
+ // Test for PLMN address
+ wsp_encode_test(MMS.Address, {address: "+123.456-789", type: "PLMN"},
+ strToCharCodeArray("+123.456-789/TYPE=PLMN"));
+ wsp_encode_test(MMS.Address, {address: "123456789", type: "PLMN"},
+ strToCharCodeArray("123456789/TYPE=PLMN"));
+ // Test for IPv4
+ wsp_encode_test(MMS.Address, {address: "1.2.3.4", type: "IPv4"},
+ strToCharCodeArray("1.2.3.4/TYPE=IPv4"));
+ // Test for IPv6
+ wsp_encode_test(MMS.Address,
+ {address: "1111:AAAA:bbbb:CdEf:1ABC:2cde:3Def:0000", type: "IPv6"},
+ strToCharCodeArray("1111:AAAA:bbbb:CdEf:1ABC:2cde:3Def:0000/TYPE=IPv6")
+ );
+ // Test for other device-address
+ wsp_encode_test(MMS.Address, {address: "+H-e.l%l_o", type: "W0r1d_"},
+ strToCharCodeArray("+H-e.l%l_o/TYPE=W0r1d_"));
+ // Test for num-shortcode
+ wsp_encode_test(MMS.Address, {address: "+123", type: "num"},
+ strToCharCodeArray("+123"));
+ wsp_encode_test(MMS.Address, {address: "*123", type: "num"},
+ strToCharCodeArray("*123"));
+ wsp_encode_test(MMS.Address, {address: "#123", type: "num"},
+ strToCharCodeArray("#123"));
+ // Test for alphanum-shortcode
+ wsp_encode_test(MMS.Address, {address: "H0wD0Y0uTurnTh1s0n", type: "alphanum"},
+ strToCharCodeArray("H0wD0Y0uTurnTh1s0n"));
+ // Test for email address
+ wsp_encode_test(MMS.Address, {address: "Joe User <joe@user.org>", type: "email"},
+ strToCharCodeArray("Joe User <joe@user.org>"));
run_next_test();
});
//
// Test target: HeaderField
//
@@ -151,16 +190,30 @@ add_test(function test_ContentClassValue
} else {
wsp_decode_test(MMS.ContentClassValue, [i], null, "CodeError");
}
}
run_next_test();
});
+//// ContentClassValue.encode ////
+
+add_test(function test_ContentClassValue_encode() {
+ for (let i = 0; i < 256; i++) {
+ if ((i >= 128) && (i <= 135)) {
+ wsp_encode_test(MMS.ContentClassValue, i, [i]);
+ } else {
+ wsp_encode_test(MMS.ContentClassValue, i, null, "CodeError");
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: ContentLocationValue
//
//// ContentLocationValue.decode ////
add_test(function test_ContentLocationValue_decode() {
// Test for MMS_PDU_TYPE_MBOX_DELETE_CONF & MMS_PDU_TYPE_DELETE_CONF
@@ -258,16 +311,34 @@ add_test(function test_Parameter_decodeM
// return MMS.Parameter.decodeMultiple(data, data.array.length);
// }, [0x80 | 0x02, 0x80 | 0x00].concat(strToCharCodeArray("good")).concat([0x80 | 0x01]),
// {type: 0, good: 1}
//);
run_next_test();
});
+//// Parameter.encode ////
+
+add_test(function test_Parameter_encode() {
+ // Test for invalid parameter value
+ wsp_encode_test(MMS.Parameter, null, null, "CodeError");
+ wsp_encode_test(MMS.Parameter, undefined, null, "CodeError");
+ wsp_encode_test(MMS.Parameter, {}, null, "CodeError");
+ // Test for case-insensitive parameter name
+ wsp_encode_test(MMS.Parameter, {name: "TYPE", value: 0}, [130, 128]);
+ wsp_encode_test(MMS.Parameter, {name: "type", value: 0}, [130, 128]);
+ // Test for non-well-known parameter name
+ wsp_encode_test(MMS.Parameter, {name: "name", value: 0}, [110, 97, 109, 101, 0, 128]);
+ // Test for constrained encoding value
+ wsp_encode_test(MMS.Parameter, {name: "type", value: "0"}, [130, 48, 0]);
+
+ run_next_test();
+});
+
//
// Test target: EncodedStringValue
//
//// EncodedStringValue.decode ////
add_test(function test_EncodedStringValue_decode() {
// Test for normal TextString
@@ -286,31 +357,64 @@ add_test(function test_EncodedStringValu
let raw = conv.convertToByteArray(str).concat([0]);
wsp_decode_test(MMS.EncodedStringValue,
[raw.length + 2, 0x80 | entry.number, 127].concat(raw), str);
}
run_next_test();
});
+//// EncodedStringValue.encode ////
+
+add_test(function test_EncodedStringValue_encode() {
+ // Test for normal TextString
+ wsp_encode_test(MMS.EncodedStringValue, "Hello", strToCharCodeArray("Hello"));
+ // Test for utf-8
+ let (entry = MMS.WSP.WSP_WELL_KNOWN_CHARSETS["utf-8"]) {
+ // "Mozilla" in full width.
+ let str = "\uff2d\uff4f\uff5a\uff49\uff4c\uff4c\uff41";
+
+ let conv = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Ci.nsIScriptableUnicodeConverter);
+ conv.charset = entry.converter;
+
+ let raw = conv.convertToByteArray(str).concat([0]);
+ wsp_encode_test(MMS.EncodedStringValue, str,
+ [raw.length + 2, 0x80 | entry.number, 127].concat(raw));
+ }
+
+ run_next_test();
+});
+
//
// Test target: ExpiryValue
//
//// ExpiryValue.decode ////
add_test(function test_ExpiryValue_decode() {
// Test for Absolute-token Date-value
wsp_decode_test(MMS.ExpiryValue, [3, 128, 1, 0x80], new Date(0x80 * 1000));
// Test for Relative-token Delta-seconds-value
wsp_decode_test(MMS.ExpiryValue, [2, 129, 0x80], 0);
run_next_test();
});
+//// ExpiryValue.encode ////
+
+add_test(function test_ExpiryValue_encode() {
+ // Test for Absolute-token Date-value
+ wsp_encode_test(MMS.ExpiryValue, new Date(0x80 * 1000), [3, 128, 1, 0x80]);
+ // Test for Relative-token Delta-seconds-value
+ wsp_encode_test(MMS.ExpiryValue, 0, [2, 129, 0x80]);
+
+ run_next_test();
+});
+
//
// Test target: PreviouslySentByValue
//
//// PreviouslySentByValue.decode ////
add_test(function test_PreviouslySentByValue_decode() {
wsp_decode_test(MMS.PreviouslySentByValue, [3, 0x80 | 0x03, 65, 0],
@@ -346,16 +450,30 @@ add_test(function test_FromValue_decode(
let (addr = strToCharCodeArray("+123/TYPE=PLMN")) {
wsp_decode_test(MMS.FromValue, [addr.length + 1, 128].concat(addr),
{address: "+123", type: "PLMN"});
}
run_next_test();
});
+//// FromValue.encode ////
+
+add_test(function test_FromValue_encode() {
+ // Test for Insert-address-token:
+ wsp_encode_test(MMS.FromValue, null, [1, 129]);
+ // Test for Address-present-token:
+ let (addr = strToCharCodeArray("+123/TYPE=PLMN")) {
+ wsp_encode_test(MMS.FromValue, {address: "+123", type: "PLMN"},
+ [addr.length + 1, 128].concat(addr));
+ }
+
+ run_next_test();
+});
+
//
// Test target: MessageClassValue
//
//// MessageClassValue.decodeClassIdentifier ////
add_test(function test_MessageClassValue_decodeClassIdentifier() {
let (IDs = ["personal", "advertisement", "informational", "auto"]) {
@@ -381,16 +499,28 @@ add_test(function test_MessageClassValue
add_test(function test_MessageClassValue_decode() {
wsp_decode_test(MMS.MessageClassValue, [65, 0], "A");
wsp_decode_test(MMS.MessageClassValue, [128], "personal");
run_next_test();
});
+//// MessageClassValue.encode ////
+
+add_test(function test_MessageClassValue_encode() {
+ wsp_encode_test(MMS.MessageClassValue, "personal", [128]);
+ wsp_encode_test(MMS.MessageClassValue, "advertisement", [129]);
+ wsp_encode_test(MMS.MessageClassValue, "informational", [130]);
+ wsp_encode_test(MMS.MessageClassValue, "auto", [131]);
+ wsp_encode_test(MMS.MessageClassValue, "A", [65, 0]);
+
+ run_next_test();
+});
+
//
// Test target: MessageTypeValue
//
//// MessageTypeValue.decode ////
add_test(function test_MessageTypeValue_decode() {
for (let i = 0; i < 256; i++) {
@@ -431,16 +561,30 @@ add_test(function test_MmFlagsValue_deco
} else {
wsp_decode_test(MMS.MmFlagsValue, [3, i, 65, 0], null, "CodeError");
}
}
run_next_test();
});
+//// MmFlagsValue.encode ////
+
+add_test(function test_MmFlagsValue_encode() {
+ for (let i = 0; i < 256; i++) {
+ if ((i >= 128) && (i <= 130)) {
+ wsp_encode_test(MMS.MmFlagsValue, {type: i, text: "A"}, [3, i, 65, 0]);
+ } else {
+ wsp_encode_test(MMS.MmFlagsValue, {type: i, text: "A"}, null, "CodeError");
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: MmStateValue
//
//// MmStateValue.decode ////
add_test(function test_MmStateValue_decode() {
for (let i = 0; i < 256; i++) {
@@ -449,16 +593,30 @@ add_test(function test_MmStateValue_deco
} else {
wsp_decode_test(MMS.MmStateValue, [i], null, "CodeError");
}
}
run_next_test();
});
+//// MmStateValue.encode ////
+
+add_test(function test_MmStateValue_encode() {
+ for (let i = 0; i < 256; i++) {
+ if ((i >= 128) && (i <= 132)) {
+ wsp_encode_test(MMS.MmStateValue, i, [i]);
+ } else {
+ wsp_encode_test(MMS.MmStateValue, i, null, "CodeError");
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: PriorityValue
//
//// PriorityValue.decode ////
add_test(function test_PriorityValue_decode() {
for (let i = 0; i < 256; i++) {
@@ -467,16 +625,30 @@ add_test(function test_PriorityValue_dec
} else {
wsp_decode_test(MMS.PriorityValue, [i], null, "CodeError");
}
}
run_next_test();
});
+//// PriorityValue.encode ////
+
+add_test(function test_PriorityValue_encode() {
+ for (let i = 0; i < 256; i++) {
+ if ((i >= 128) && (i <= 130)) {
+ wsp_encode_test(MMS.PriorityValue, i, [i]);
+ } else {
+ wsp_encode_test(MMS.PriorityValue, i, null, "CodeError");
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: RecommendedRetrievalModeValue
//
//// RecommendedRetrievalModeValue.decode ////
add_test(function test_RecommendedRetrievalModeValue_decode() {
for (let i = 0; i < 256; i++) {
@@ -503,16 +675,68 @@ add_test(function test_ReplyChargingValu
} else {
wsp_decode_test(MMS.ReplyChargingValue, [i], null, "CodeError");
}
}
run_next_test();
});
+//// ReplyChargingValue.encode ////
+
+add_test(function test_ReplyChargingValue_encode() {
+ for (let i = 0; i < 256; i++) {
+ if ((i >= 128) && (i <= 131)) {
+ wsp_encode_test(MMS.ReplyChargingValue, i, [i]);
+ } else {
+ wsp_encode_test(MMS.ReplyChargingValue, i, null, "CodeError");
+ }
+ }
+
+ run_next_test();
+});
+
+//
+// Test target: ResponseText
+//
+
+//// ResponseText.decode ////
+
+add_test(function test_ResponseText_decode() {
+ // Test for MMS_PDU_TYPE_MBOX_DELETE_CONF & MMS_PDU_TYPE_DELETE_CONF
+ wsp_decode_test_ex(function (data) {
+ data.array[0] = data.array.length - 1;
+
+ let options = {};
+ options["x-mms-message-type"] = MMS_PDU_TYPE_MBOX_DELETE_CONF;
+ return MMS.ResponseText.decode(data, options);
+ }, [0, 0x80 | 0x00].concat(strToCharCodeArray("http://no.such.com/path")),
+ {statusCount: 0, text: "http://no.such.com/path"}
+ );
+ wsp_decode_test_ex(function (data) {
+ data.array[0] = data.array.length - 1;
+
+ let options = {};
+ options["x-mms-message-type"] = MMS_PDU_TYPE_DELETE_CONF;
+ return MMS.ResponseText.decode(data, options);
+ }, [0, 0x80 | 0x00].concat(strToCharCodeArray("http://no.such.com/path")),
+ {statusCount: 0, text: "http://no.such.com/path"}
+ );
+ // Test for other situations
+ wsp_decode_test_ex(function (data) {
+ let options = {};
+ options["x-mms-message-type"] = MMS_PDU_TYPE_SEND_REQ;
+ return MMS.ResponseText.decode(data, options);
+ }, strToCharCodeArray("http://no.such.com/path"),
+ {text: "http://no.such.com/path"}
+ );
+
+ run_next_test();
+});
+
//
// Test target: RetrieveStatusValue
//
//// RetrieveStatusValue.decode ////
add_test(function test_RetrieveStatusValue_decode() {
for (let i = 0; i < 256; i++) {
@@ -577,17 +801,17 @@ add_test(function test_PduHelper_parseHe
let expect = {};
expect["x-mms-mms-version"] = MMS_VERSION;
expect["content-type"] = {
media: "application/vnd.wap.multipart.related",
params: null,
};
parse([0x80 | 0x0D, 0x80 | MMS_VERSION, // X-Mms-Mms-Version: 1.3
0x80 | 0x04, 0x80 | 0x33, // Content-Type: application/vnd.wap.multipart.related
- 0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
+ 0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
], expect);
// Parse header fields with multiple entries
expect = {
to: [
{ address: "+123", type: "PLMN" },
{ address: "+456", type: "num" },
],
@@ -598,8 +822,88 @@ add_test(function test_PduHelper_parseHe
};
parse(Array.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
.concat([0x80 | 0x17]).concat(strToCharCodeArray("+456"))
.concat([0x80 | 0x04, 0x80 | 0x33]),
expect);
run_next_test();
});
+
+//// PduHelper.encodeHeader ////
+
+add_test(function test_PduHelper_encodeHeader() {
+ function func(name, data, headers) {
+ MMS.PduHelper.encodeHeader(data, headers, name);
+
+ // Remove extra space consumed during encoding.
+ while (data.array.length > data.offset) {
+ data.array.pop();
+ }
+
+ return data.array;
+ }
+
+ // Encode header fields with multiple entries
+ let headers = {
+ to: [
+ { address: "+123", type: "PLMN" },
+ { address: "+456", type: "num" },
+ ],
+ };
+ wsp_encode_test_ex(func.bind(null, "to"), headers,
+ Array.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
+ .concat([0x80 | 0x17]).concat(strToCharCodeArray("+456")));
+
+ run_next_test();
+});
+
+//// PduHelper.encodeHeaderIfExists ////
+
+add_test(function test_PduHelper_encodeHeaderIfExists() {
+ function func(name, data, headers) {
+ MMS.PduHelper.encodeHeaderIfExists(data, headers, name);
+
+ // Remove extra space consumed during encoding.
+ while (data.array.length > data.offset) {
+ data.array.pop();
+ }
+
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func.bind(null, "to"), {}, []);
+
+ run_next_test();
+});
+
+//// PduHelper.encodeHeaders ////
+
+add_test(function test_PduHelper_encodeHeaders() {
+ function func(data, headers) {
+ MMS.PduHelper.encodeHeaders(data, headers);
+
+ // Remove extra space consumed during encoding.
+ while (data.array.length > data.offset) {
+ data.array.pop();
+ }
+
+ return data.array;
+ }
+
+ let headers = {};
+ headers["x-mms-message-type"] = MMS_PDU_TYPE_SEND_REQ;
+ headers["x-mms-mms-version"] = MMS_VERSION;
+ headers["x-mms-transaction-id"] = "asdf";
+ headers["to"] = { address: "+123", type: "PLMN" };
+ headers["content-type"] = {
+ media: "application/vnd.wap.multipart.related",
+ };
+ wsp_encode_test_ex(func, headers,
+ Array.concat([0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ])
+ .concat([0x80 | 0x18]).concat(strToCharCodeArray(headers["x-mms-transaction-id"]))
+ .concat([0x80 | 0x0D, 0x80 | MMS_VERSION])
+ .concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
+ .concat([0x80 | 0x04, 0x80 | 0x33]));
+
+ run_next_test();
+});
+
--- a/dom/mms/tests/test_wsp_pdu_helper.js
+++ b/dom/mms/tests/test_wsp_pdu_helper.js
@@ -102,16 +102,27 @@ add_test(function test_Octet_decodeEqual
add_test(function test_Octet_encode() {
for (let i = 0; i < 256; i++) {
wsp_encode_test(WSP.Octet, i, [i]);
}
run_next_test();
});
+//// Octet.encodeMultiple ////
+
+add_test(function test_Octet_encodeMultiple() {
+ wsp_encode_test_ex(function (data, input) {
+ WSP.Octet.encodeMultiple(data, input);
+ return data.array;
+ }, [0, 1, 2, 3], [0, 1, 2, 3]);
+
+ run_next_test();
+});
+
//
// Test target: Text
//
//// Text.decode ////
add_test(function test_Text_decode() {
for (let i = 0; i < 256; i++) {
@@ -298,16 +309,24 @@ add_test(function test_QuotedString_deco
wsp_decode_test(WSP.QuotedString, [32, 0], null, "CodeError");
// Test incompleted string
wsp_decode_test(WSP.QuotedString, [34, 32], null, "RangeError");
wsp_decode_test(WSP.QuotedString, [34, 32, 0], " ");
run_next_test();
});
+//// QuotedString.encode ////
+
+add_test(function test_QuotedString_encode() {
+ wsp_encode_test(WSP.QuotedString, "B2G", [34].concat(strToCharCodeArray("B2G")));
+
+ run_next_test();
+});
+
//
// Test target: ShortInteger
//
//// ShortInteger.decode ////
add_test(function test_ShortInteger_decode() {
for (let i = 0; i < 256; i++) {
@@ -336,32 +355,63 @@ add_test(function test_ShortInteger_enco
});
//
// Test target: LongInteger
//
//// LongInteger.decode ////
-function LongInteger_testcases(target) {
+function LongInteger_decode_testcases(target) {
// Test LongInteger of zero octet
wsp_decode_test(target, [0, 0], null, "CodeError");
wsp_decode_test(target, [1, 0x80], 0x80);
wsp_decode_test(target, [2, 0x80, 2], 0x8002);
wsp_decode_test(target, [3, 0x80, 2, 3], 0x800203);
wsp_decode_test(target, [4, 0x80, 2, 3, 4], 0x80020304);
wsp_decode_test(target, [5, 0x80, 2, 3, 4, 5], 0x8002030405);
wsp_decode_test(target, [6, 0x80, 2, 3, 4, 5, 6], 0x800203040506);
// Test LongInteger of more than 6 octets
wsp_decode_test(target, [7, 0x80, 2, 3, 4, 5, 6, 7], [0x80, 2, 3, 4, 5, 6, 7]);
// Test LongInteger of more than 30 octets
wsp_decode_test(target, [31], null, "CodeError");
}
add_test(function test_LongInteger_decode() {
- LongInteger_testcases(WSP.LongInteger);
+ LongInteger_decode_testcases(WSP.LongInteger);
+
+ run_next_test();
+});
+
+//// LongInteger.encode ////
+
+function LongInteger_encode_testcases(target) {
+ wsp_encode_test(target, 0x80, [1, 0x80]);
+ wsp_encode_test(target, 0x8002, [2, 0x80, 2]);
+ wsp_encode_test(target, 0x800203, [3, 0x80, 2, 3]);
+ wsp_encode_test(target, 0x80020304, [4, 0x80, 2, 3, 4]);
+ wsp_encode_test(target, 0x8002030405, [5, 0x80, 2, 3, 4, 5]);
+ wsp_encode_test(target, 0x800203040506, [6, 0x80, 2, 3, 4, 5, 6]);
+ // Test LongInteger of more than 6 octets
+ wsp_encode_test(target, 0x1000000000000, null, "CodeError");
+ // Test input empty array
+ wsp_encode_test(target, [], null, "CodeError");
+ // Test input octets array of length 1..30
+ let array = [];
+ for (let i = 1; i <= 30; i++) {
+ array.push(i);
+ wsp_encode_test(target, array, [i].concat(array));
+ }
+ // Test input octets array of 31 elements.
+ array.push(31);
+ wsp_encode_test(target, array, null, "CodeError");
+}
+add_test(function test_LongInteger_encode() {
+ wsp_encode_test(WSP.LongInteger, 0, [1, 0]);
+
+ LongInteger_encode_testcases(WSP.LongInteger);
run_next_test();
});
//
// Test target: UintVar
//
@@ -380,29 +430,55 @@ add_test(function test_UintVar_decode()
wsp_decode_test(WSP.UintVar, [0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F], 0x1FFFFFFFFFFFFF);
wsp_decode_test(WSP.UintVar, [0x01, 0x02], 1);
wsp_decode_test(WSP.UintVar, [0x80, 0x01, 0x02], 1);
wsp_decode_test(WSP.UintVar, [0x80, 0x80, 0x80, 0x01, 0x2], 1);
run_next_test();
});
+//// UintVar.encode ////
+
+add_test(function test_UintVar_encode() {
+ // Test up to max 53 bits integer
+ wsp_encode_test(WSP.UintVar, 0, [0]);
+ wsp_encode_test(WSP.UintVar, 0x7F, [0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x3FFF, [0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x1FFFFF, [0xFF, 0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0xFFFFFFF, [0xFF, 0xFF, 0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x7FFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x3FFFFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x1FFFFFFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+ wsp_encode_test(WSP.UintVar, 0x1FFFFFFFFFFFFF, [0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+
+ run_next_test();
+});
+
//
-// Test target: ConstrainedEncoding (decodeAlternatives)
+// Test target: ConstrainedEncoding
//
//// ConstrainedEncoding.decode ////
add_test(function test_ConstrainedEncoding_decode() {
wsp_decode_test(WSP.ConstrainedEncoding, [0x80], 0);
wsp_decode_test(WSP.ConstrainedEncoding, [32, 0], " ");
run_next_test();
});
+//// ConstrainedEncoding.encode ////
+
+add_test(function test_ConstrainedEncoding_encode() {
+ wsp_encode_test(WSP.ConstrainedEncoding, 0, [0x80 | 0]);
+ wsp_encode_test(WSP.ConstrainedEncoding, "A", [65, 0]);
+
+ run_next_test();
+});
+
//
// Test target: ValueLength
//
//// ValueLength.decode ////
add_test(function test_ValueLength_decode() {
for (let i = 0; i < 256; i++) {
@@ -413,58 +489,111 @@ add_test(function test_ValueLength_decod
} else {
wsp_decode_test(WSP.ValueLength, [i, 0x8F, 0x7F], null, "CodeError");
}
}
run_next_test();
});
+//// ValueLength.encode ////
+
+add_test(function test_ValueLength_encode() {
+ for (let i = 0; i < 256; i++) {
+ if (i < 31) {
+ wsp_encode_test(WSP.ValueLength, i, [i]);
+ } else if (i < 128) {
+ wsp_encode_test(WSP.ValueLength, i, [31, i]);
+ } else {
+ wsp_encode_test(WSP.ValueLength, i, [31, (0x80 | (i / 128)), i % 128]);
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: NoValue
//
//// NoValue.decode ////
add_test(function test_NoValue_decode() {
wsp_decode_test(WSP.NoValue, [0], null);
for (let i = 1; i < 256; i++) {
wsp_decode_test(WSP.NoValue, [i], null, "CodeError");
}
run_next_test();
});
+//// NoValue.encode ////
+
+add_test(function test_NoValue_encode() {
+ wsp_encode_test(WSP.NoValue, undefined, [0]);
+ wsp_encode_test(WSP.NoValue, null, [0]);
+ wsp_encode_test(WSP.NoValue, 0, null, "CodeError");
+ wsp_encode_test(WSP.NoValue, "", null, "CodeError");
+ wsp_encode_test(WSP.NoValue, [], null, "CodeError");
+ wsp_encode_test(WSP.NoValue, {}, null, "CodeError");
+
+ run_next_test();
+});
+
//
// Test target: TextValue
//
//// TextValue.decode ////
add_test(function test_TextValue_decode() {
wsp_decode_test(WSP.TextValue, [0], null);
wsp_decode_test(WSP.TextValue, [65, 0], "A");
wsp_decode_test(WSP.TextValue, [32, 0], null, "CodeError");
wsp_decode_test(WSP.TextValue, [34, 32, 0], " ");
run_next_test();
});
+//// TextValue.encode ////
+
+add_test(function test_TextValue_encode() {
+ wsp_encode_test(WSP.TextValue, undefined, [0]);
+ wsp_encode_test(WSP.TextValue, null, [0]);
+ wsp_encode_test(WSP.TextValue, "", [0]);
+ wsp_encode_test(WSP.TextValue, "A", [65, 0]);
+ wsp_encode_test(WSP.TextValue, "\x80", [34, 128, 0]);
+
+ run_next_test();
+});
+
//
// Test target: IntegerValue
//
//// IntegerValue.decode ////
add_test(function test_IntegerValue_decode() {
for (let i = 128; i < 256; i++) {
wsp_decode_test(WSP.IntegerValue, [i], i & 0x7F);
}
- LongInteger_testcases(WSP.IntegerValue);
+ LongInteger_decode_testcases(WSP.IntegerValue);
+
+ run_next_test();
+});
+
+//// IntegerValue.decode ////
+
+add_test(function test_IntegerValue_encode() {
+ for (let i = 0; i < 128; i++) {
+ wsp_encode_test(WSP.IntegerValue, i, [0x80 | i]);
+ }
+
+ LongInteger_encode_testcases(WSP.IntegerValue);
run_next_test();
});
//
// Test target: DateValue
//
@@ -473,16 +602,24 @@ add_test(function test_IntegerValue_deco
add_test(function test_DateValue_decode() {
wsp_decode_test(WSP.DateValue, [0, 0], null, "CodeError");
wsp_decode_test(WSP.DateValue, [1, 0x80], new Date(0x80 * 1000));
wsp_decode_test(WSP.DateValue, [31], null, "CodeError");
run_next_test();
});
+//// DateValue.encode ////
+
+add_test(function test_DateValue_encode() {
+ wsp_encode_test(WSP.DateValue, new Date(0x80 * 1000), [1, 0x80]);
+
+ run_next_test();
+});
+
//
// Test target: DeltaSecondsValue
//
// DeltaSecondsValue is only an alias of IntegerValue.
//
// Test target: QValue
//
@@ -495,16 +632,28 @@ add_test(function test_QValue_decode() {
wsp_decode_test(WSP.QValue, [100], 0.99);
wsp_decode_test(WSP.QValue, [101], 0.001);
wsp_decode_test(WSP.QValue, [0x88, 0x4B], 0.999);
wsp_decode_test(WSP.QValue, [0x88, 0x4C], null, "CodeError");
run_next_test();
});
+//// QValue.encode ////
+
+add_test(function test_QValue_encode() {
+ wsp_encode_test(WSP.QValue, 0, [1]);
+ wsp_encode_test(WSP.QValue, 0.99, [100]);
+ wsp_encode_test(WSP.QValue, 0.001, [101]);
+ wsp_encode_test(WSP.QValue, 0.999, [0x88, 0x4B]);
+ wsp_encode_test(WSP.QValue, 1, null, "CodeError");
+
+ run_next_test();
+});
+
//
// Test target: VersionValue
//
//// VersionValue.decode ////
add_test(function test_VersionValue_decode() {
for (let major = 1; major < 8; major++) {
@@ -521,16 +670,32 @@ add_test(function test_VersionValue_deco
wsp_decode_test(WSP.VersionValue, [major + 0x30, 0x2E, minor + 0x30, 0], version);
}
}
}
run_next_test();
});
+//// VersionValue.encode ////
+
+add_test(function test_VersionValue_encode() {
+ for (let major = 1; major < 8; major++) {
+ let version = (major << 4) | 0x0F;
+ wsp_encode_test(WSP.VersionValue, version, [0x80 | version]);
+
+ for (let minor = 0; minor < 15; minor++) {
+ version = (major << 4) | minor;
+ wsp_encode_test(WSP.VersionValue, version, [0x80 | version]);
+ }
+ }
+
+ run_next_test();
+});
+
//
// Test target: UriValue
//
//// UriValue.decode ////
add_test(function test_UriValue_decode() {
wsp_decode_test(WSP.UriValue, [97], null, "RangeError");
@@ -553,16 +718,27 @@ add_test(function test_TypeValue_decode(
wsp_decode_test(WSP.TypeValue, [0x33 | 0x80],
"application/vnd.wap.multipart.related");
// Test for NotWellKnownEncodingError
wsp_decode_test(WSP.TypeValue, [0x80], null, "NotWellKnownEncodingError");
run_next_test();
});
+//// TypeValue.encode ////
+
+add_test(function test_TypeValue_encode() {
+ wsp_encode_test(WSP.TypeValue, "no/such.type",
+ [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+ wsp_encode_test(WSP.TypeValue, "application/vnd.wap.multipart.related",
+ [0x33 | 0x80]);
+
+ run_next_test();
+});
+
//
// Test target: Parameter
//
//// Parameter.decodeTypedParameter ////
add_test(function test_Parameter_decodeTypedParameter() {
function func(data) {
@@ -576,20 +752,20 @@ add_test(function test_Parameter_decodeT
// Test for NotWellKnownEncodingError
wsp_decode_test_ex(func, [1, 0xFF], null, "NotWellKnownEncodingError");
// Test for parameter specific decoder
wsp_decode_test_ex(func, [1, 0, 100], {name: "q", value: 0.99});
// Test for TextValue
wsp_decode_test_ex(func, [1, 0x10, 48, 46, 57, 57, 0],
{name: "secure", value: "0.99"});
// Test for TextString
- wsp_decode_test_ex(func, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
+ wsp_decode_test_ex(func, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0],
{name: "start", value: "<smil>"});
// Test for skipValue
- wsp_decode_test_ex(func, [1, 0x19, 128], null);
+ wsp_decode_test_ex(func, [1, 0x0A, 128], null);
run_next_test();
});
//// Parameter.decodeUntypedParameter ////
add_test(function test_Parameter_decodeUntypedParameter() {
function func (data) {
@@ -604,34 +780,87 @@ add_test(function test_Parameter_decodeU
wsp_decode_test_ex(func, [65, 0, 66, 0], {name: "a", value: "B"});
run_next_test();
});
//// Parameter.decode ////
add_test(function test_Parameter_decode() {
- wsp_decode_test(WSP.Parameter, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
+ wsp_decode_test(WSP.Parameter, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0],
{name: "start", value: "<smil>"});
wsp_decode_test(WSP.Parameter, [65, 0, 66, 0], {name: "a", value: "B"});
run_next_test();
});
//// Parameter.decodeMultiple ////
add_test(function test_Parameter_decodeMultiple() {
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeMultiple(data, 13);
- }, [1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0], {start: "<smil>", a: "B"}
+ }, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0], {start: "<smil>", a: "B"}
);
run_next_test();
});
+//// Parameter.encodeTypedParameter ////
+
+add_test(function test_Parameter_encodeTypedParameter() {
+ function func(data, input) {
+ WSP.Parameter.encodeTypedParameter(data, input);
+ return data.array;
+ }
+
+ // Test for NotWellKnownEncodingError
+ wsp_encode_test_ex(func, {name: "xxx", value: 0}, null, "NotWellKnownEncodingError");
+ wsp_encode_test_ex(func, {name: "q", value: 0}, [0x80, 1]);
+ wsp_encode_test_ex(func, {name: "name", value: "A"}, [0x85, 65, 0]);
+
+ run_next_test();
+});
+
+//// Parameter.encodeUntypedParameter ////
+
+add_test(function test_Parameter_encodeUntypedParameter() {
+ function func(data, input) {
+ WSP.Parameter.encodeUntypedParameter(data, input);
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func, {name: "q", value: 0}, [113, 0, 0x80]);
+ wsp_encode_test_ex(func, {name: "name", value: "A"}, [110, 97, 109, 101, 0, 65, 0]);
+
+ run_next_test();
+});
+
+//// Parameter.encodeMultiple ////
+
+add_test(function test_Parameter_encodeMultiple() {
+ function func(data, input) {
+ WSP.Parameter.encodeMultiple(data, input);
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func, {q: 0, n: "A"}, [0x80, 1, 110, 0, 65, 0]);
+
+ run_next_test();
+});
+
+//// Parameter.encode ////
+
+add_test(function test_Parameter_encode() {
+
+ wsp_encode_test(WSP.Parameter, {name: "q", value: 0}, [0x80, 1]);
+ wsp_encode_test(WSP.Parameter, {name: "n", value: "A"}, [110, 0, 65, 0]);
+
+ run_next_test();
+});
+
//
// Test target: Header
//
//// Header.decode ////
add_test(function test_Header_decode() {
wsp_decode_test(WSP.Header, [0x34 | 0x80, 0x80], {name: "push-flag", value: 0});
@@ -717,16 +946,25 @@ add_test(function test_FieldName_decode(
let (entry = WSP.WSP_HEADER_FIELDS["content-length"]) {
wsp_decode_test(WSP.FieldName, [entry.number | 0x80], entry.name);
}
wsp_decode_test(WSP.FieldName, [0xFF], null, "NotWellKnownEncodingError");
run_next_test();
});
+//// FieldName.encode ////
+
+add_test(function test_FieldName_encode() {
+ wsp_encode_test(WSP.FieldName, "", [0]);
+ wsp_encode_test(WSP.FieldName, "date", [0x92]);
+
+ run_next_test();
+});
+
//
// Test target: AcceptCharsetValue
//
//// AcceptCharsetValue.decode ////
add_test(function test_AcceptCharsetValue_decode() {
wsp_decode_test(WSP.AcceptCharsetValue, [0xFF], null, "CodeError");
@@ -743,16 +981,34 @@ add_test(function test_AcceptCharsetValu
wsp_decode_test(WSP.AcceptCharsetValue, [2, 1, entry.number], {charset: entry.name});
wsp_decode_test(WSP.AcceptCharsetValue, [1, entry.number | 0x80], {charset: entry.name});
}
wsp_decode_test(WSP.AcceptCharsetValue, [3, 65, 0, 100], {charset: "A", q: 0.99});
run_next_test();
});
+//// AcceptCharsetValue.encodeAnyCharset ////
+
+add_test(function test_AcceptCharsetValue_encodeAnyCharset() {
+ function func(data, input) {
+ WSP.AcceptCharsetValue.encodeAnyCharset(data, input);
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func, null, [0x80]);
+ wsp_encode_test_ex(func, undefined, [0x80]);
+ wsp_encode_test_ex(func, {}, [0x80]);
+ wsp_encode_test_ex(func, {charset: null}, [0x80]);
+ wsp_encode_test_ex(func, {charset: "*"}, [0x80]);
+ wsp_encode_test_ex(func, {charset: "en"}, null, "CodeError");
+
+ run_next_test();
+});
+
//
// Test target: WellKnownCharset
//
//// WellKnownCharset.decode ////
add_test(function test_WellKnownCharset_decode() {
wsp_decode_test(WSP.WellKnownCharset, [0xFF], null, "NotWellKnownEncodingError");
@@ -761,16 +1017,26 @@ add_test(function test_WellKnownCharset_
// Test for number-typed return value from IntegerValue
wsp_decode_test(WSP.WellKnownCharset, [1, 3], {charset: "ansi_x3.4-1968"});
// Test for array-typed return value from IntegerValue
wsp_decode_test(WSP.WellKnownCharset, [7, 0, 0, 0, 0, 0, 0, 0, 3], null, "CodeError");
run_next_test();
});
+//// WellKnownCharset.encode ////
+
+add_test(function test_WellKnownCharset_encode() {
+ // Test for Any-charset
+ wsp_encode_test(WSP.WellKnownCharset, {charset: "*"}, [0x80]);
+ wsp_encode_test(WSP.WellKnownCharset, {charset: "UTF-8"}, [128 + 106]);
+
+ run_next_test();
+});
+
//
// Test target: ContentTypeValue
//
//// ContentTypeValue.decodeConstrainedMedia ////
add_test(function test_ContentTypeValue_decodeConstrainedMedia() {
function func(data) {
@@ -809,50 +1075,114 @@ add_test(function test_ContentTypeValue_
add_test(function test_ContentTypeValue_decodeMediaType() {
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeMediaType(data, 1);
}, [0x3E | 0x80],
{media: "application/vnd.wap.mms-message", params: null}
);
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeMediaType(data, 14);
- }, [0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+ }, [0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
{media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
);
run_next_test();
});
//// ContentTypeValue.decodeContentGeneralForm ////
add_test(function test_ContentTypeValue_decodeContentGeneralForm() {
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeContentGeneralForm(data);
- }, [14, 0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+ }, [14, 0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
{media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
);
run_next_test();
});
//// ContentTypeValue.decode ////
add_test(function test_ContentTypeValue_decode() {
wsp_decode_test(WSP.ContentTypeValue,
- [14, 0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+ [14, 0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
{media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
);
wsp_decode_test(WSP.ContentTypeValue, [0x33 | 0x80],
{media: "application/vnd.wap.multipart.related", params: null}
);
run_next_test();
});
+//// ContentTypeValue.encodeConstrainedMedia ////
+
+add_test(function test_ContentTypeValue_encodeConstrainedMedia() {
+ function func(data, input) {
+ WSP.ContentTypeValue.encodeConstrainedMedia(data, input);
+ return data.array;
+ }
+
+ // Test media type with additional parameters.
+ wsp_encode_test_ex(func, {media: "a", params: [{a: "b"}]}, null, "CodeError");
+ wsp_encode_test_ex(func, {media: "no/such.type"},
+ [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+ wsp_encode_test_ex(func, {media: "application/vnd.wap.multipart.related"},
+ [0x33 | 0x80]);
+
+ run_next_test();
+});
+
+//// ContentTypeValue.encodeMediaType ////
+
+add_test(function test_ContentTypeValue_encodeMediaType() {
+ function func(data, input) {
+ WSP.ContentTypeValue.encodeMediaType(data, input);
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func, {media: "no/such.type"},
+ [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+ wsp_encode_test_ex(func, {media: "application/vnd.wap.multipart.related"},
+ [0x33 | 0x80]);
+ wsp_encode_test_ex(func, {media: "a", params: {b: "c", q: 0}},
+ [97, 0, 98, 0, 99, 0, 128, 1]);
+
+ run_next_test();
+});
+
+//// ContentTypeValue.encodeContentGeneralForm ////
+
+add_test(function test_ContentTypeValue_encodeContentGeneralForm() {
+ function func(data, input) {
+ WSP.ContentTypeValue.encodeContentGeneralForm(data, input);
+ return data.array;
+ }
+
+ wsp_encode_test_ex(func, {media: "a", params: {b: "c", q: 0}},
+ [8, 97, 0, 98, 0, 99, 0, 128, 1]);
+
+ run_next_test();
+});
+
+//// ContentTypeValue.encode ////
+
+add_test(function test_ContentTypeValue_encode() {
+ wsp_encode_test(WSP.ContentTypeValue, {media: "no/such.type"},
+ [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+ wsp_encode_test(WSP.ContentTypeValue,
+ {media: "application/vnd.wap.multipart.related"},
+ [0x33 | 0x80]);
+ wsp_encode_test(WSP.ContentTypeValue, {media: "a", params: {b: "c", q: 0}},
+ [8, 97, 0, 98, 0, 99, 0, 128, 1]);
+
+ run_next_test();
+});
+
//
// Test target: ApplicationIdValue
//
//// ApplicationIdValue.decode ////
add_test(function test_ApplicationIdValue_decode() {
wsp_decode_test(WSP.ApplicationIdValue, [0], "");
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -88,16 +88,17 @@ using mozilla::PluginPRLibrary;
using mozilla::plugins::PluginModuleParent;
#ifdef MOZ_X11
#include "mozilla/X11Util.h"
#endif
#ifdef XP_WIN
#include <windows.h>
+#include "nsWindowsHelpers.h"
#endif
#ifdef MOZ_WIDGET_ANDROID
#include <android/log.h>
#include "android_npapi.h"
#include "ANPBase.h"
#include "AndroidBridge.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
@@ -276,30 +277,16 @@ static bool GMA9XXGraphics()
}
}
::CGLDestroyRendererInfo(renderer);
}
return hasIntelGMA9XX;
}
#endif
-#ifdef XP_WIN
-static bool
-IsVistaOrLater()
-{
- OSVERSIONINFO info;
-
- ZeroMemory(&info, sizeof(OSVERSIONINFO));
- info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&info);
-
- return info.dwMajorVersion >= 6;
-}
-#endif
-
bool
nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
{
if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
return false;
}
if (!aPluginTag) {
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -213,21 +213,25 @@ nsNPAPIPluginInstance::~nsNPAPIPluginIns
void
nsNPAPIPluginInstance::Destroy()
{
Stop();
mPlugin = nsnull;
#if MOZ_WIDGET_ANDROID
+ if (mContentSurface)
+ mContentSurface->SetFrameAvailableCallback(nsnull);
+
mContentTexture = nsnull;
mContentSurface = nsnull;
std::map<void*, VideoInfo*>::iterator it;
for (it = mVideos.begin(); it != mVideos.end(); it++) {
+ it->second->mSurfaceTexture->SetFrameAvailableCallback(nsnull);
delete it->second;
}
mVideos.clear();
SetWakeLock(false);
#endif
}
TimeStamp
@@ -983,21 +987,27 @@ nsSurfaceTexture* nsNPAPIPluginInstance:
GLuint texture = TexturePoolOGL::AcquireTexture();
if (!texture)
return nsnull;
nsSurfaceTexture* surface = nsSurfaceTexture::Create(texture);
if (!surface)
return nsnull;
- nsCOMPtr<nsIRunnable> frameCallback = NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::RedrawPlugin);
+ nsCOMPtr<nsIRunnable> frameCallback = NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
surface->SetFrameAvailableCallback(frameCallback);
return surface;
}
+void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
+{
+ if (mRunning == RUNNING && mOwner)
+ RedrawPlugin();
+}
+
void* nsNPAPIPluginInstance::AcquireContentWindow()
{
if (!mContentSurface) {
mContentSurface = CreateSurfaceTexture();
if (!mContentSurface)
return nsnull;
}
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -281,16 +281,17 @@ protected:
#ifdef MOZ_WIDGET_ANDROID
PRUint32 mANPDrawingModel;
friend class PluginEventRunnable;
nsTArray<nsCOMPtr<PluginEventRunnable>> mPostedEvents;
void PopPostedEvent(PluginEventRunnable* r);
+ void OnSurfaceTextureFrameAvailable();
PRUint32 mFullScreenOrientation;
bool mWakeLocked;
bool mFullScreen;
bool mInverted;
nsRefPtr<SharedPluginTexture> mContentTexture;
nsRefPtr<nsSurfaceTexture> mContentSurface;
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1917,17 +1917,17 @@ PluginInstanceParent::SharedSurfaceRelea
{
mSharedSurfaceDib.Close();
}
bool
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
NPRemoteWindow& aRemoteWindow)
{
- aRemoteWindow.window = nsnull;
+ aRemoteWindow.window = 0;
aRemoteWindow.x = aWindow->x;
aRemoteWindow.y = aWindow->y;
aRemoteWindow.width = aWindow->width;
aRemoteWindow.height = aWindow->height;
aRemoteWindow.type = aWindow->type;
nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -94,18 +94,16 @@ NS_IMPL_ISUPPORTS1(AutoMounterSetting, n
NS_IMETHODIMP
AutoMounterSetting::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
return NS_OK;
}
- LOG("%s: detected %s data = '%s'", __FUNCTION__, aTopic,
- NS_LossyConvertUTF16toASCII(aData).get());
// Note that this function gets called for any and all settings changes,
// so we need to carefully check if we have the one we're interested in.
//
// The string that we're interested in will be a JSON string that looks like:
// {"key":"ums.autoMount","value":true}
nsCOMPtr<nsIThreadJSContextStack> stack =
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -455,16 +455,17 @@ const MSISDN_MAX_NUMBER_SIZE_BYTES = 10;
const READ_RECORD_ABSOLUTE_MODE = 4;
// GET_RESPONSE mandatory response size for EF, see TS 51.011 clause 9,
// 'Response data in case of an EF.'
const GET_RESPONSE_EF_SIZE_BYTES = 15;
// EF path
const EF_PATH_MF_SIM = "3f00";
+const EF_PATH_DF_PHONEBOOK = "5f3a";
const EF_PATH_DF_TELECOM = "7f10";
const EF_PATH_DF_GSM = "7f20";
// Status code of sw1 for ICC I/O,
// see GSM11.11 and TS 51.011 clause 9.4, and ISO 7816-4
const ICC_STATUS_NORMAL_ENDING = 0x90;
const ICC_STATUS_NORMAL_ENDING_WITH_EXTRA = 0x91;
const ICC_STATUS_WITH_SIM_DATA = 0x9e;
--- a/dom/telephony/test/marionette/pdu_builder.js
+++ b/dom/telephony/test/marionette/pdu_builder.js
@@ -1,12 +1,17 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
+let Cu = SpecialPowers.wrap(Components).utils;
+let RIL = {};
+
+Cu.import("resource://gre/modules/ril_consts.js", RIL);
+
// Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
// that code turns out to be a nightmare, so there is some code duplication.
let PDUBuilder = {
toHexString: function toHexString(n, length) {
let str = n.toString(16);
if (str.length < length) {
for (let i = 0; i < length - str.length; i++) {
str = "0" + str;
@@ -41,42 +46,42 @@ let PDUBuilder = {
}
},
writeStringAsSeptets: function writeStringAsSeptets(message,
paddingBits,
langIndex,
langShiftIndex)
{
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
+ const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
+ const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
let dataBits = paddingBits;
let data = 0;
for (let i = 0; i < message.length; i++) {
let septet = langTable.indexOf(message[i]);
- if (septet == PDU_NL_EXTENDED_ESCAPE) {
+ if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
continue;
}
if (septet >= 0) {
data |= septet << dataBits;
dataBits += 7;
} else {
septet = langShiftTable.indexOf(message[i]);
if (septet == -1) {
throw new Error(message[i] + " not in 7 bit alphabet "
+ langIndex + ":" + langShiftIndex + "!");
}
- if (septet == PDU_NL_RESERVED_CONTROL) {
+ if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
continue;
}
- data |= PDU_NL_EXTENDED_ESCAPE << dataBits;
+ data |= RIL.PDU_NL_EXTENDED_ESCAPE << dataBits;
dataBits += 7;
data |= septet << dataBits;
dataBits += 7;
}
for (; dataBits >= 8; dataBits -= 8) {
this.writeHexOctet(data & 0xFF);
data >>>= 8;
@@ -84,19 +89,19 @@ let PDUBuilder = {
}
if (dataBits != 0) {
this.writeHexOctet(data & 0xFF);
}
},
buildAddress: function buildAddress(address) {
- let addressFormat = PDU_TOA_ISDN; // 81
+ let addressFormat = RIL.PDU_TOA_ISDN; // 81
if (address[0] == '+') {
- addressFormat = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
+ addressFormat = RIL.PDU_TOA_INTERNATIONAL | RIL.PDU_TOA_ISDN; // 91
address = address.substring(1);
}
this.buf = "";
this.writeHexOctet(address.length);
this.writeHexOctet(addressFormat);
this.writeSwappedNibbleBCD(address);
@@ -137,13 +142,13 @@ let PDUBuilder = {
for each (let octet in header.octets) {
this.writeHexOctet(octet);
}
}
}
}
this.writeStringAsSeptets(options.body, paddingBits,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
+ RIL.PDU_NL_IDENTIFIER_DEFAULT,
+ RIL.PDU_NL_IDENTIFIER_DEFAULT);
return this.buf;
}
};
--- a/dom/telephony/test/marionette/test_voicemail_statuschanged.js
+++ b/dom/telephony/test/marionette/test_voicemail_statuschanged.js
@@ -9,17 +9,17 @@ let voicemail = window.navigator.mozVoic
ok(voicemail instanceof MozVoicemail);
is(voicemail.status, null);
function sendIndicatorPDU(pdu, listener, nextTest) {
let smsCommand = "sms pdu " + pdu;
let commandCompleted = false;
let sawEvent = false;
- voicemail.addEventListener("statuschanged", function statusChanged(event) {
+ voicemail.addEventListener("statuschanged", function statusChanged(event) {
voicemail.removeEventListener("statuschanged", statusChanged);
try {
listener(event);
} catch (e) {
ok(false, String(e));
}
@@ -146,20 +146,20 @@ function testLevel2DiscardInactive() {
// Tests for Level 3 MWI with a message count in the User Data Header
const MWI_LEVEL3_SENDER = "+15125551236";
const MWI_LEVEL3_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL3_SENDER);
const MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT = 3;
const MWI_LEVEL3_ACTIVE_BODY = "3 new voicemails";
const MWI_LEVEL3_ACTIVE_UD = PDUBuilder.buildUserData({
headers: [{
- id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
+ id: RIL.PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
length: 2,
octets: [
- PDU_MWI_STORE_TYPE_DISCARD,
+ RIL.PDU_MWI_STORE_TYPE_DISCARD,
MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT
]
}],
body: MWI_LEVEL3_ACTIVE_BODY
});
const MWI_LEVEL3_DISCARD_ACTIVE_PDU =
MWI_PDU_UDH_PREFIX +
@@ -184,20 +184,20 @@ function testLevel3DiscardActive() {
sendIndicatorPDU(MWI_LEVEL3_DISCARD_ACTIVE_PDU,
onLevel3Active,
testLevel3DiscardInactive);
}
const MWI_LEVEL3_INACTIVE_BODY = "No unread voicemails";
const MWI_LEVEL3_INACTIVE_UD = PDUBuilder.buildUserData({
headers: [{
- id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
+ id: RIL.PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
length: 2,
octets: [
- PDU_MWI_STORE_TYPE_DISCARD,
+ RIL.PDU_MWI_STORE_TYPE_DISCARD,
0 // messageCount
]
}],
body: MWI_LEVEL3_INACTIVE_BODY
});
const MWI_LEVEL3_DISCARD_INACTIVE_PDU =
MWI_PDU_UDH_PREFIX +
--- a/dom/telephony/test/marionette/test_voicemail_statuschanged.py
+++ b/dom/telephony/test/marionette/test_voicemail_statuschanged.py
@@ -1,20 +1,14 @@
from marionette_test import MarionetteTestCase
import os
class TestVoicemailStatusChanged(MarionetteTestCase):
def testStatusChanged(self):
this_dir = os.path.abspath(os.path.dirname(__file__))
- system_gonk_dir = os.path.abspath(os.path.join(this_dir,
- os.path.pardir, os.path.pardir, os.path.pardir, "system", "gonk"))
-
- ril_consts_path = os.path.join(system_gonk_dir, "ril_consts.js")
- self.marionette.import_script(ril_consts_path)
-
pdu_builder_path = os.path.join(this_dir, "pdu_builder.js")
self.marionette.import_script(pdu_builder_path)
test_path = os.path.join(this_dir, "test_voicemail_statuschanged.js")
test = open(test_path, "r").read()
self.marionette.set_script_timeout(30000)
self.marionette.execute_async_script(test)
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1599,20 +1599,24 @@ XMLHttpRequest::MaybeDispatchPrematureAb
void
XMLHttpRequest::DispatchPrematureAbortEvent(JSObject* aTarget,
uint8_t aEventType,
bool aUploadTarget,
ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
- MOZ_ASSERT(mProxy);
MOZ_ASSERT(aTarget);
MOZ_ASSERT(aEventType <= STRING_COUNT);
+ if (!mProxy) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return;
+ }
+
JSContext* cx = GetJSContext();
JSString* type = JS_NewStringCopyZ(cx, sEventStrings[aEventType]);
if (!type) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
--- a/dom/workers/test/test_xhrAbort.html
+++ b/dom/workers/test/test_xhrAbort.html
@@ -30,21 +30,15 @@ Tests of DOM Worker Threads XHR(Bug 4504
worker.onmessage = function(event) {
is (data.toString(), event.data.toString(), "Got different results!");
SimpleTest.finish();
};
worker.postMessage("start");
}
- SimpleTest.waitForExplicitFinish();
+ runTest();
- const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
- if (isWinXP){
- todo(false, "Test disabled on WinXP due to bug 718260 crashes");
- SimpleTest.finish();
- } else {
- runTest();
- }
+ SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>
--- a/editor/composer/src/Makefile.in
+++ b/editor/composer/src/Makefile.in
@@ -27,17 +27,18 @@ CPPSRCS = \
nsComposerRegistration.cpp \
nsEditingSession.cpp \
nsComposerCommandsUpdater.cpp \
nsEditorSpellCheck.cpp \
$(NULL)
include $(topsrcdir)/config/rules.mk
-INCLUDES += -I../../libeditor/base/src
+INCLUDES += \
+ $(NULL)
_FILES = \
$(srcdir)/res/EditorOverride.css \
$(srcdir)/res/grabber.gif \
$(srcdir)/res/table-add-column-after-active.gif \
$(srcdir)/res/table-add-column-after-hover.gif \
$(srcdir)/res/table-add-column-after.gif \
$(srcdir)/res/table-add-column-before-active.gif \
--- a/extensions/auth/nsAuthGSSAPI.cpp
+++ b/extensions/auth/nsAuthGSSAPI.cpp
@@ -562,8 +562,14 @@ nsAuthGSSAPI::Wrap(const void *inToken,
/* it is not possible for output_token.length to be zero */
*outToken = nsMemory::Clone(output_token.value, output_token.length);
gss_release_buffer_ptr(&minor_status, &output_token);
return NS_OK;
}
+NS_IMETHODIMP
+nsAuthGSSAPI::GetModuleProperties(PRUint32 *flags)
+{
+ *flags = 0;
+ return NS_OK;
+}
--- a/extensions/auth/nsAuthSASL.cpp
+++ b/extensions/auth/nsAuthSASL.cpp
@@ -144,8 +144,15 @@ NS_IMETHODIMP
nsAuthSASL::Wrap(const void *inToken,
PRUint32 inTokenLen,
bool confidential,
void **outToken,
PRUint32 *outTokenLen)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
+
+NS_IMETHODIMP
+nsAuthSASL::GetModuleProperties(PRUint32 *flags)
+{
+ *flags = 0;
+ return NS_OK;
+}
--- a/extensions/auth/nsAuthSSPI.cpp
+++ b/extensions/auth/nsAuthSSPI.cpp
@@ -86,60 +86,16 @@ InitSSPI()
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
-static nsresult
-MakeSN(const char *principal, nsCString &result)
-{
- nsresult rv;
-
- nsCAutoString buf(principal);
-
- // The service name looks like "protocol@hostname", we need to map
- // this to a value that SSPI expects. To be consistent with IE, we
- // need to map '@' to '/' and canonicalize the hostname.
- PRInt32 index = buf.FindChar('@');
- if (index == kNotFound)
- return NS_ERROR_UNEXPECTED;
-
- nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
- if (NS_FAILED(rv))
- return rv;
-
- // This could be expensive if our DNS cache cannot satisfy the request.
- // However, we should have at least hit the OS resolver once prior to
- // reaching this code, so provided the OS resolver has this information
- // cached, we should not have to worry about blocking on this function call
- // for very long. NOTE: because we ask for the canonical hostname, we
- // might end up requiring extra network activity in cases where the OS
- // resolver might not have enough information to satisfy the request from
- // its cache. This is not an issue in versions of Windows up to WinXP.
- nsCOMPtr<nsIDNSRecord> record;
- rv = dns->Resolve(Substring(buf, index + 1),
- nsIDNSService::RESOLVE_CANONICAL_NAME,
- getter_AddRefs(record));
- if (NS_FAILED(rv))
- return rv;
-
- nsCAutoString cname;
- rv = record->GetCanonicalName(cname);
- if (NS_SUCCEEDED(rv)) {
- result = StringHead(buf, index) + NS_LITERAL_CSTRING("/") + cname;
- LOG(("Using SPN of [%s]\n", result.get()));
- }
- return rv;
-}
-
-//-----------------------------------------------------------------------------
-
nsAuthSSPI::nsAuthSSPI(pType package)
: mServiceFlags(REQ_DEFAULT)
, mMaxTokenLen(0)
, mPackage(package)
, mCertDERData(nsnull)
, mCertDERLength(0)
{
memset(&mCred, 0, sizeof(mCred));
@@ -203,33 +159,23 @@ nsAuthSSPI::Init(const char *serviceName
rv = InitSSPI();
if (NS_FAILED(rv))
return rv;
}
SEC_WCHAR *package;
package = (SEC_WCHAR *) pTypeName[(int)mPackage];
- if (mPackage == PACKAGE_TYPE_NTLM) {
- // (bug 535193) For NTLM, just use the uri host, do not do canonical host lookups.
- // The incoming serviceName is in the format: "protocol@hostname", SSPI expects
- // "<service class>/<hostname>", so swap the '@' for a '/'.
- mServiceName.Assign(serviceName);
- PRInt32 index = mServiceName.FindChar('@');
- if (index == kNotFound)
- return NS_ERROR_UNEXPECTED;
- mServiceName.Replace(index, 1, '/');
- }
- else {
- // Kerberos requires the canonical host, MakeSN takes care of this through a
- // DNS lookup.
- rv = MakeSN(serviceName, mServiceName);
- if (NS_FAILED(rv))
- return rv;
- }
+ // The incoming serviceName is in the format: "protocol@hostname", SSPI expects
+ // "<service class>/<hostname>", so swap the '@' for a '/'.
+ mServiceName.Assign(serviceName);
+ PRInt32 index = mServiceName.FindChar('@');
+ if (index == kNotFound)
+ return NS_ERROR_UNEXPECTED;
+ mServiceName.Replace(index, 1, '/');
mServiceFlags = serviceFlags;
SECURITY_STATUS rc;
PSecPkgInfoW pinfo;
rc = (sspi->QuerySecurityPackageInfoW)(package, &pinfo);
if (rc != SEC_E_OK) {
@@ -648,8 +594,21 @@ nsAuthSSPI::Wrap(const void *inToken,
memcpy(p,bufs.ib[2].pvBuffer, bufs.ib[2].cbBuffer);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
+
+NS_IMETHODIMP
+nsAuthSSPI::GetModuleProperties(PRUint32 *flags)
+{
+ *flags = 0;
+
+ // (bug 535193) For NTLM, just use the uri host, do not do canonical host
+ // lookups. But Kerberos requires the canonical host.
+ if (mPackage != PACKAGE_TYPE_NTLM)
+ *flags |= CANONICAL_NAME_REQUIRED;
+
+ return NS_OK;
+}
--- a/extensions/auth/nsAuthSambaNTLM.cpp
+++ b/extensions/auth/nsAuthSambaNTLM.cpp
@@ -277,8 +277,15 @@ NS_IMETHODIMP
nsAuthSambaNTLM::Wrap(const void *inToken,
PRUint32 inTokenLen,
bool confidential,
void **outToken,
PRUint32 *outTokenLen)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::GetModuleProperties(PRUint32 *flags)
+{
+ *flags = 0;
+ return NS_OK;
+}
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -201,20 +201,24 @@ void SetPaintPattern(SkPaint& aPaint, co
points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));
SkShader* shader = SkGradientShader::CreateLinear(points,
&stops->mColors.front(),
&stops->mPositions.front(),
stops->mCount,
mode);
- SkMatrix mat;
- GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
- shader->setLocalMatrix(mat);
- SkSafeUnref(aPaint.setShader(shader));
+
+ if (shader) {
+ SkMatrix mat;
+ GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
+ shader->setLocalMatrix(mat);
+ SkSafeUnref(aPaint.setShader(shader));
+ }
+
} else {
aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
}
break;
}
case PATTERN_RADIAL_GRADIENT: {
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
@@ -228,20 +232,23 @@ void SetPaintPattern(SkPaint& aPaint, co
SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0],
SkFloatToScalar(pat.mRadius1),
points[1],
SkFloatToScalar(pat.mRadius2),
&stops->mColors.front(),
&stops->mPositions.front(),
stops->mCount,
mode);
- SkMatrix mat;
- GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
- shader->setLocalMatrix(mat);
- SkSafeUnref(aPaint.setShader(shader));
+ if (shader) {
+ SkMatrix mat;
+ GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
+ shader->setLocalMatrix(mat);
+ SkSafeUnref(aPaint.setShader(shader));
+ }
+
} else {
aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
}
break;
}
case PATTERN_SURFACE: {
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(pat.mSurface.get())->GetBitmap();
--- a/gfx/angle/AUTHORS
+++ b/gfx/angle/AUTHORS
@@ -8,8 +8,10 @@
# The email address is not required for organizations.
TransGaming Inc.
Google Inc.
3DLabs Inc. Ltd.
+Cloud Party, Inc.
+
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -12,16 +12,17 @@ TransGaming Inc.
Andrew Lewycky
Gavriel State
Shannon Woods
Google Inc.
Brent Austin
Michael Bai
John Bauman
+ Steve Block
Henry Bridge
Nat Duca
Vangelis Kokkevis
Zhenyao Mo
Daniel Nicoara
Alastair Patrick
Alok Priyadarshi
Kenneth Russell
@@ -34,18 +35,26 @@ Mozilla Corp.
Mike Hommey
Benoit Jacob
Makoto Kato
Vladimir Vukicevic
Apple Inc.
David Kilzer
+Adobe Systems Inc.
+ Alexandru Chiculita
+ Max Vujovic
+
+Cloud Party, Inc.
+ Conor Dickinson
+
Aitor Moreno <aitormoreno at gmail.com>
Jim Hauxwell <james at dattrax.co.uk>
ddefrostt
timeless
Yore Apex
Mark Callow
Yuriy O'Donnell
Sam Hocevar
Pierre Leveille
+Jin Yang
--- a/gfx/angle/DEPS
+++ b/gfx/angle/DEPS
@@ -1,14 +1,17 @@
deps = {
"trunk/third_party/gyp":
"http://gyp.googlecode.com/svn/trunk@1080",
"trunk/third_party/googletest":
"http://googletest.googlecode.com/svn/trunk@573", #release 1.6.0
+
+ "trunk/third_party/googlemock":
+ "http://googlemock.googlecode.com/svn/trunk@387", #release 1.6.0
}
hooks = [
{
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
"pattern": ".",
"action": ["python", "trunk/build/gyp_angle"],
},
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -24,48 +24,63 @@ EXPORTS_angle = \
$(NULL)
LOCAL_INCLUDES += -I$(srcdir)/include -I$(srcdir)/src
VPATH += $(srcdir)/src
VPATH += $(srcdir)/src/compiler
VPATH += $(srcdir)/src/compiler/preprocessor
VPATH += $(srcdir)/src/compiler/preprocessor/new
+VPATH += $(srcdir)/src/compiler/timing
+VPATH += $(srcdir)/src/compiler/depgraph
CPPSRCS = \
- Compiler.cpp \
+ Diagnostics.cpp \
+ PreprocessorDiagnostics.cpp \
+ DirectiveHandler.cpp \
+ PreprocessorDirectiveHandler.cpp \
+ DirectiveParser.cpp \
+ ExpressionParser.cpp \
+ Macro.cpp \
+ MacroExpander.cpp \
+ Tokenizer.cpp \
+ InitializeParseContext.cpp \
+ DependencyGraph.cpp \
+ DependencyGraphBuilder.cpp \
+ DependencyGraphOutput.cpp \
+ DependencyGraphTraverse.cpp \
+ RestrictFragmentShaderTiming.cpp \
+ RestrictVertexShaderTiming.cpp \
+ Compiler.cpp \
DetectRecursion.cpp \
InfoSink.cpp \
Initialize.cpp \
InitializeDll.cpp \
Intermediate.cpp \
intermOut.cpp \
IntermTraverse.cpp \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
QualifierAlive.cpp \
RemoveTree.cpp \
ShaderLang.cpp \
SymbolTable.cpp \
VariableInfo.cpp \
compilerdebug.cpp \
- ossource_nspr.cpp \
util.cpp \
ValidateLimitations.cpp \
ForLoopUnroll.cpp \
MapLongVariableNames.cpp \
spooky.cpp \
BuiltInFunctionEmulator.cpp \
Input.cpp \
Lexer.cpp \
- pp_lex.cpp \
Preprocessor.cpp \
Token.cpp \
- lexer_glue.cpp \
$(NULL)
# flex/yacc generated files
CPPSRCS += \
glslang_lex.cpp \
glslang_tab.cpp \
$(NULL)
@@ -73,45 +88,40 @@ CPPSRCS += \
CPPSRCS += \
CodeGenGLSL.cpp \
OutputGLSL.cpp \
TranslatorGLSL.cpp \
VersionGLSL.cpp \
OutputESSL.cpp \
OutputGLSLBase.cpp \
TranslatorESSL.cpp \
- $(NULL)
-
-# Currently, only one or the other
-# can be selected.
+ $(NULL)
-## HLSL translator backend
-##CPPSRCS += \
-## CodeGenHLSL.cpp \
-## OutputHLSL.cpp \
-## TranslatorHLSL.cpp \
-## UnfoldSelect.cpp \
-## SearchSymbol.cpp \
-## $(NULL)
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+CPPSRCS += ossource_win.cpp $(NULL)
+else
+CPPSRCS += ossource_posix.cpp $(NULL)
+endif
CSRCS = \
atom.c \
cpp.c \
cppstruct.c \
memory.c \
scanner.c \
symbols.c \
tokens.c \
- $(NULL)
+ $(NULL)
-DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
+DEFINES += -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
#these defines are from ANGLE's build_angle.gyp
DEFINES += -DANGLE_DISABLE_TRACE
DEFINES += -DANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0
+DEFINES += -DANGLE_USE_NEW_PREPROCESSOR=1
ifdef MOZ_ANGLE_RENDERER
# libEGL depends on (links against!) libGLESv2!
DIRS = src/libGLESv2 src/libEGL
libs::
expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,23 +1,40 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/
-Current revision: r1042
+Current revision: r1242
== Applied local patches ==
In this order:
- angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
- angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
- angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
- angle-enforce-readpixels-spec.patch - see bug 724476.
- angle-impl-read-bgra.patch - see bug 724476.
- angle-long-identifier-hash-spooky.patch - see bug 676071
+
+ angle-renaming-debug.patch
+ rename debug.h to compilerdebug.h to avoid conflict in our makefiles
+
+ angle-renaming-preprocessor-diagonostics.patch
+ rename one of the two Diagnostics.cpp to avoid conflict in our makefiles
+
+ angle-renaming-preprocessor-directivehandler.patch
+ rename one of the two DirectiveHandler.cpp to avoid conflict in our makefiles
+
+ angle-enforce-readpixels-spec.patch
+ see bug 724476
+
+ angle-impl-read-bgra.patch
+ see bug 724476
+
+ gfx/angle/angle-long-identifier-hash-spooky.patch
+ see bug 676071
+
+ angle-abort-on-oom-in-preprocessor.patch
+ see bug 680840. Probably not useful anymore now that we're on the new
+ preprocessor, but it doesn't hurt to keep it around a bit longer.
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
+Therefore, changes made to the Makefile.in files should not be stored in the local .patch files.
== How to update this ANGLE copy ==
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
4. Check for changes in src/build_angle.gyp, update our Makefile.in files accordingly. Note that a single file may be recorded in more than one Makefile.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-abort-on-oom-in-preprocessor.patch
@@ -0,0 +1,29 @@
+# HG changeset patch
+# Parent 11023ab3d23865b71678e9a4b22a45646ec0c0f0
+diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
+--- a/gfx/angle/src/compiler/preprocessor/atom.c
++++ b/gfx/angle/src/compiler/preprocessor/atom.c
+@@ -327,22 +327,17 @@ static int GrowAtomTable(AtomTable *atab
+ newmap = realloc(atable->amap, sizeof(int)*size);
+ newrev = realloc(atable->arev, sizeof(int)*size);
+ } else {
+ newmap = malloc(sizeof(int)*size);
+ newrev = malloc(sizeof(int)*size);
+ atable->size = 0;
+ }
+ if (!newmap || !newrev) {
+- /* failed to grow -- error */
+- if (newmap)
+- atable->amap = newmap;
+- if (newrev)
+- atable->arev = newrev;
+- return -1;
++ abort();
+ }
+ memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
+ memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
+ atable->amap = newmap;
+ atable->arev = newrev;
+ atable->size = size;
+ }
+ return 0;
deleted file mode 100644
--- a/gfx/angle/angle-castrate-bug-241.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-# HG changeset patch
-# User Benoit Jacob <bjacob@mozilla.com>
-# Parent 7dcbce54a953090ae8e537f93c6c99ab8eb0dc62
-
-diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
---- a/gfx/angle/README.mozilla
-+++ b/gfx/angle/README.mozilla
-@@ -4,16 +4,17 @@ Current revision: r963
-
- == Applied local patches ==
-
- In this order:
- angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
- angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
- angle-limit-identifiers-to-250-chars.patch - see bug 675625
- angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
-+ angle-castrate-bug-241.patch - see bug 699033 / angle bug 241
-
- In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
-
- == How to update this ANGLE copy ==
-
- 1. Unapply patches
- 2. Apply diff with new ANGLE version
- 3. Reapply patches.
-diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
---- a/gfx/angle/src/compiler/Types.h
-+++ b/gfx/angle/src/compiler/Types.h
-@@ -5,16 +5,17 @@
- //
-
- #ifndef _TYPES_INCLUDED
- #define _TYPES_INCLUDED
-
- #include "compiler/BaseTypes.h"
- #include "compiler/Common.h"
- #include "compiler/compilerdebug.h"
-+#include <cstdlib>
-
- //
- // Need to have association of line numbers to types in a list for building structs.
- //
- class TType;
- struct TTypeLine {
- TType* type;
- int line;
-@@ -203,17 +204,17 @@ public:
- bool isVector() const { return size > 1 && !matrix; }
- bool isScalar() const { return size == 1 && !matrix && !structure; }
-
- TTypeList* getStruct() const { return structure; }
- void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
-
- const TString& getTypeName() const
- {
-- assert(typeName);
-+ if(!typeName) abort();
- return *typeName;
- }
- void setTypeName(const TString& n)
- {
- typeName = NewPoolTString(n.c_str());
- }
-
- bool isField() const { return fieldName != 0; }
--- a/gfx/angle/angle-enforce-readpixels-spec.patch
+++ b/gfx/angle/angle-enforce-readpixels-spec.patch
@@ -1,14 +1,14 @@
# HG changeset patch
-# Parent 8d84c8d4e3ed41a4941afdf9d51819b19ca64716
+# Parent a1fed68f51737972901e0d6fc829d3e044a453bd
diff --git a/gfx/angle/src/libGLESv2/libGLESv2.cpp b/gfx/angle/src/libGLESv2/libGLESv2.cpp
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
-@@ -98,27 +98,16 @@ bool validReadFormatType(GLenum format,
+@@ -231,27 +231,16 @@ bool validReadFormatType(GLenum format,
switch (type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return false;
}
break;
--- a/gfx/angle/angle-impl-read-bgra.patch
+++ b/gfx/angle/angle-impl-read-bgra.patch
@@ -1,14 +1,14 @@
# HG changeset patch
-# Parent 8b838be49f115022e403c850c24b28ad62d72ad6
+# Parent 97ded57f965865c06306a8ef82d082064542caff
diff --git a/gfx/angle/src/libGLESv2/Context.cpp b/gfx/angle/src/libGLESv2/Context.cpp
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
-@@ -2518,16 +2518,17 @@ void Context::readPixels(GLint x, GLint
+@@ -2585,16 +2585,17 @@ void Context::readPixels(GLint x, GLint
{
if (desc.Format == D3DFMT_A8R8G8B8 &&
format == GL_BGRA_EXT &&
type == GL_UNSIGNED_BYTE)
{
// Fast path for EXT_read_format_bgra, given
// an RGBA source buffer. Note that buffers with no
// alpha go through the slow path below.
@@ -16,17 +16,17 @@ diff --git a/gfx/angle/src/libGLESv2/Con
memcpy(dest + j * outputPitch,
source + j * inputPitch,
(rect.right - rect.left) * 4);
continue;
}
for (int i = 0; i < rect.right - rect.left; i++)
{
-@@ -2665,20 +2666,20 @@ void Context::readPixels(GLint x, GLint
+@@ -2732,20 +2733,20 @@ void Context::readPixels(GLint x, GLint
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |
((unsigned short)(31 * b + 0.5f) << 0);
break;
default: UNREACHABLE();
}
break;
deleted file mode 100644
--- a/gfx/angle/angle-intrinsic-msvc2005.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-# HG changeset patch
-# Parent 4ef86d96d456866537beea57b0a4451cf919cd34
-diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
---- a/gfx/angle/src/libGLESv2/Texture.cpp
-+++ b/gfx/angle/src/libGLESv2/Texture.cpp
-@@ -8,16 +8,22 @@
- // Texture2D and TextureCubeMap. Implements GL texture objects and related
- // functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
-
- #include "libGLESv2/Texture.h"
-
- #include <d3dx9tex.h>
-
- #include <algorithm>
-+
-+#if _MSC_VER <= 1400
-+#define _interlockedbittestandreset _interlockedbittestandreset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#define _interlockedbittestandset _interlockedbittestandset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#endif
-+
- #include <intrin.h>
-
- #include "common/debug.h"
-
- #include "libEGL/Display.h"
-
- #include "libGLESv2/main.h"
- #include "libGLESv2/mathutil.h"
-diff --git a/gfx/angle/src/libGLESv2/mathutil.h b/gfx/angle/src/libGLESv2/mathutil.h
---- a/gfx/angle/src/libGLESv2/mathutil.h
-+++ b/gfx/angle/src/libGLESv2/mathutil.h
-@@ -3,16 +3,21 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- //
-
- // mathutil.h: Math and bit manipulation functions.
-
- #ifndef LIBGLESV2_MATHUTIL_H_
- #define LIBGLESV2_MATHUTIL_H_
-+
-+#if _MSC_VER <= 1400
-+#define _interlockedbittestandreset _interlockedbittestandreset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#define _interlockedbittestandset _interlockedbittestandset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#endif
-
- #include <intrin.h>
- #include <math.h>
- #include <windows.h>
-
- namespace gl
- {
- inline bool isPow2(int x)
--- a/gfx/angle/angle-long-identifier-hash-spooky.patch
+++ b/gfx/angle/angle-long-identifier-hash-spooky.patch
@@ -1,35 +1,15 @@
# HG changeset patch
-# Parent 268bda9ac676b6f4cca5aa044d0dcefff2008535
-diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
---- a/gfx/angle/Makefile.in
-+++ b/gfx/angle/Makefile.in
-@@ -79,16 +79,17 @@ CPPSRCS = \
- SymbolTable.cpp \
- VariableInfo.cpp \
- compilerdebug.cpp \
- ossource_nspr.cpp \
- util.cpp \
- ValidateLimitations.cpp \
- ForLoopUnroll.cpp \
- MapLongVariableNames.cpp \
-+ spooky.cpp \
- BuiltInFunctionEmulator.cpp \
- $(NULL)
-
- # flex/yacc generated files
- CPPSRCS += \
- glslang_lex.cpp \
- glslang_tab.cpp \
- $(NULL)
+# Parent c5e7517cbb1c38ce9821ba3deca88768b4dff066
+
diff --git a/gfx/angle/src/compiler/MapLongVariableNames.cpp b/gfx/angle/src/compiler/MapLongVariableNames.cpp
--- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
-@@ -1,27 +1,30 @@
+@@ -1,29 +1,36 @@
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/MapLongVariableNames.h"
+#include "spooky.h"
@@ -38,25 +18,33 @@ diff --git a/gfx/angle/src/compiler/MapL
TString mapLongName(int id, const TString& name, bool isGlobal)
{
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
TStringStream stream;
- stream << "webgl_";
- if (isGlobal)
- stream << "g";
-- stream << id << "_";
+- stream << id;
+- if (name[0] != '_')
+- stream << "_";
- stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
+ uint64 hash = SpookyHash::Hash64(name.data(), name.length(), 0);
-+ stream << "webgl_"
++
++ // We want to avoid producing a string with a double underscore,
++ // which would be an illegal GLSL identifier. We can assume that the
++ // original identifier doesn't have a double underscore, otherwise
++ // it's illegal anyway.
++ stream << (name[0] == '_' ? "webgl" : "webgl_")
+ << name.substr(0, 9)
-+ << "_"
++ << (name[8] == '_' ? "" : "_")
+ << std::hex
+ << hash;
-+ ASSERT(stream.str().length() == MAX_SHORTENED_IDENTIFIER_SIZE);
++ ASSERT(stream.str().length() <= MAX_SHORTENED_IDENTIFIER_SIZE);
++ ASSERT(stream.str().length() >= MAX_SHORTENED_IDENTIFIER_SIZE - 2);
return stream.str();
}
LongNameMap* gLongNameMapInstance = NULL;
} // anonymous namespace
LongNameMap::LongNameMap()
@@ -706,50 +694,8 @@ new file mode 100644
+ uint64 m_data[2*sc_numVars]; // unhashed data, for partial messages
+ uint64 m_state[sc_numVars]; // internal state of the hash
+ size_t m_length; // total length of the input so far
+ uint8 m_remainder; // length of unhashed data stashed in m_data
+};
+
+
+
-diff --git a/gfx/angle/src/libEGL/Makefile.in b/gfx/angle/src/libEGL/Makefile.in
---- a/gfx/angle/src/libEGL/Makefile.in
-+++ b/gfx/angle/src/libEGL/Makefile.in
-@@ -91,16 +91,17 @@ CPPSRCS = \
- SymbolTable.cpp \
- VariableInfo.cpp \
- compilerdebug.cpp \
- ossource_win.cpp \
- util.cpp \
- ValidateLimitations.cpp \
- ForLoopUnroll.cpp \
- MapLongVariableNames.cpp \
-+ spooky.cpp \
- BuiltInFunctionEmulator.cpp \
- $(NULL)
-
- # flex/yacc generated files
- CPPSRCS += \
- glslang_lex.cpp \
- glslang_tab.cpp \
- $(NULL)
-diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
---- a/gfx/angle/src/libGLESv2/Makefile.in
-+++ b/gfx/angle/src/libGLESv2/Makefile.in
-@@ -91,16 +91,17 @@ CPPSRCS = \
- SymbolTable.cpp \
- VariableInfo.cpp \
- compilerdebug.cpp \
- ossource_win.cpp \
- util.cpp \
- ValidateLimitations.cpp \
- ForLoopUnroll.cpp \
- MapLongVariableNames.cpp \
-+ spooky.cpp \
- BuiltInFunctionEmulator.cpp \
- $(NULL)
-
- # flex/yacc generated files
- CPPSRCS += \
- glslang_lex.cpp \
- glslang_tab.cpp \
- $(NULL)
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,32 +1,55 @@
# HG changeset patch
-# Parent f22671e05062a082c7b22192868b804fbf42653b
-diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
---- a/gfx/angle/Makefile.in
-+++ b/gfx/angle/Makefile.in
-@@ -73,17 +73,17 @@ CPPSRCS = \
- parseConst.cpp \
- ParseHelper.cpp \
- PoolAlloc.cpp \
- QualifierAlive.cpp \
- RemoveTree.cpp \
- ShaderLang.cpp \
- SymbolTable.cpp \
- VariableInfo.cpp \
-- debug.cpp \
-+ compilerdebug.cpp \
- ossource_nspr.cpp \
- util.cpp \
- ValidateLimitations.cpp \
- ForLoopUnroll.cpp \
- MapLongVariableNames.cpp \
- BuiltInFunctionEmulator.cpp \
- $(NULL)
+# Parent 8e2ee5b1a34208fd10f501fdee330878e20df599
+
+diff --git a/gfx/angle/src/compiler/Diagnostics.cpp b/gfx/angle/src/compiler/Diagnostics.cpp
+--- a/gfx/angle/src/compiler/Diagnostics.cpp
++++ b/gfx/angle/src/compiler/Diagnostics.cpp
+@@ -1,17 +1,17 @@
+ //
+ // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ //
+
+ #include "compiler/Diagnostics.h"
+
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/InfoSink.h"
+ #include "compiler/preprocessor/new/SourceLocation.h"
+ TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
+ mInfoSink(infoSink),
+ mNumErrors(0),
+ mNumWarnings(0)
+ {
+diff --git a/gfx/angle/src/compiler/DirectiveHandler.cpp b/gfx/angle/src/compiler/DirectiveHandler.cpp
+--- a/gfx/angle/src/compiler/DirectiveHandler.cpp
++++ b/gfx/angle/src/compiler/DirectiveHandler.cpp
+@@ -3,17 +3,17 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ //
+
+ #include "compiler/DirectiveHandler.h"
+
+ #include <sstream>
+
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/Diagnostics.h"
+
+ static TBehavior getBehavior(const std::string& str)
+ {
+ static const std::string kRequire("require");
+ static const std::string kEnable("enable");
+ static const std::string kDisable("disable");
+ static const std::string kWarn("warn");
diff --git a/gfx/angle/src/compiler/OutputGLSLBase.cpp b/gfx/angle/src/compiler/OutputGLSLBase.cpp
--- a/gfx/angle/src/compiler/OutputGLSLBase.cpp
+++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp
@@ -1,16 +1,16 @@
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -41,35 +64,35 @@ diff --git a/gfx/angle/src/compiler/Outp
TString getTypeName(const TType& type)
{
TInfoSinkBase out;
if (type.isMatrix())
{
diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/OutputHLSL.cpp
--- a/gfx/angle/src/compiler/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/OutputHLSL.cpp
-@@ -1,17 +1,17 @@
- //
+@@ -2,17 +2,17 @@
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/OutputHLSL.h"
+ #include "common/angleutils.h"
-#include "compiler/debug.h"
+#include "compiler/compilerdebug.h"
#include "compiler/InfoSink.h"
- #include "compiler/UnfoldSelect.h"
+ #include "compiler/UnfoldShortCircuit.h"
#include "compiler/SearchSymbol.h"
+ #include "compiler/DetectDiscontinuity.h"
#include <stdio.h>
#include <algorithm>
- namespace sh
diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
--- a/gfx/angle/src/compiler/Types.h
+++ b/gfx/angle/src/compiler/Types.h
@@ -4,17 +4,17 @@
// found in the LICENSE file.
//
#ifndef _TYPES_INCLUDED
@@ -82,41 +105,44 @@ diff --git a/gfx/angle/src/compiler/Type
//
// Need to have association of line numbers to types in a list for building structs.
//
class TType;
struct TTypeLine {
TType* type;
int line;
-diff --git a/gfx/angle/src/compiler/compilerdebug.cpp b/gfx/angle/src/compiler/compilerdebug.cpp
---- a/gfx/angle/src/compiler/compilerdebug.cpp
+diff --git a/gfx/angle/src/compiler/debug.cpp b/gfx/angle/src/compiler/compilerdebug.cpp
+rename from gfx/angle/src/compiler/debug.cpp
+rename to gfx/angle/src/compiler/compilerdebug.cpp
+--- a/gfx/angle/src/compiler/debug.cpp
+++ b/gfx/angle/src/compiler/compilerdebug.cpp
@@ -1,17 +1,17 @@
//