зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
2aaf3a1659
|
@ -27,6 +27,7 @@
|
|||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
@ -102,8 +103,19 @@ HyperTextAccessible::NativeState()
|
|||
{
|
||||
uint64_t states = AccessibleWrap::NativeState();
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
nsCOMPtr<nsITextControlElement> textControl = do_QueryInterface(mContent);
|
||||
bool editable = !!textControl;
|
||||
Accessible* hyperText = this;
|
||||
while (!editable && hyperText) {
|
||||
if (hyperText->IsHyperText())
|
||||
editable = hyperText->GetNode()->IsEditable();
|
||||
if (hyperText->IsDoc())
|
||||
break;
|
||||
|
||||
hyperText = hyperText->Parent();
|
||||
}
|
||||
|
||||
if (editable) {
|
||||
states |= states::EDITABLE;
|
||||
|
||||
} else if (mContent->Tag() == nsGkAtoms::article) {
|
||||
|
|
|
@ -733,17 +733,29 @@
|
|||
states: STATE_PROTECTED,
|
||||
extraStates: EXT_STATE_EDITABLE,
|
||||
actions: "activate",
|
||||
children: [ ]
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF
|
||||
}
|
||||
]
|
||||
};
|
||||
testElm("input_password", obj);
|
||||
ok(getAccessible("input_password").firstChild.name != "44",
|
||||
"text leaf for password shouldn't have its real value as its name!");
|
||||
|
||||
obj = {
|
||||
role: ROLE_PASSWORD_TEXT,
|
||||
states: STATE_PROTECTED | STATE_READONLY,
|
||||
actions: "activate",
|
||||
children: [ ]
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF
|
||||
}
|
||||
]
|
||||
};
|
||||
testElm("input_password_readonly", obj);
|
||||
ok(getAccessible("input_password_readonly").firstChild.name != "44",
|
||||
"text leaf for password shouldn't have its real value as its name!");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HTML:input@type="radio"
|
||||
|
|
|
@ -378,8 +378,7 @@ let AdbController = {
|
|||
|
||||
// Check if we have a remote debugging session going on. If so, we won't
|
||||
// disable adb even if the screen is locked.
|
||||
let isDebugging = DebuggerServer._connections &&
|
||||
Object.keys(DebuggerServer._connections).length > 0;
|
||||
let isDebugging = RemoteDebugger.isDebugging;
|
||||
if (this.DEBUG) {
|
||||
this.debug("isDebugging=" + isDebugging);
|
||||
}
|
||||
|
@ -460,6 +459,8 @@ SettingsListener.observe("lockscreen.enabled", false,
|
|||
AdbController.setLockscreenEnabled.bind(AdbController));
|
||||
#endif
|
||||
|
||||
// Keep the old setting to not break people that won't have updated
|
||||
// gaia and gecko.
|
||||
SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) {
|
||||
Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
|
||||
// This preference is consulted during startup
|
||||
|
@ -475,6 +476,30 @@ SettingsListener.observe('devtools.debugger.remote-enabled', false, function(val
|
|||
#endif
|
||||
});
|
||||
|
||||
SettingsListener.observe('debugger.remote-mode', false, function(value) {
|
||||
if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) {
|
||||
dump('Illegal value for debugger.remote-mode: ' + value + '\n');
|
||||
return;
|
||||
}
|
||||
|
||||
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
|
||||
value == 'adb-devtools');
|
||||
// This preference is consulted during startup
|
||||
Services.prefs.savePrefFile(null);
|
||||
|
||||
try {
|
||||
(value == 'adb-devtools') ? RemoteDebugger.start()
|
||||
: RemoteDebugger.stop();
|
||||
} catch(e) {
|
||||
dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
AdbController.setRemoteDebuggerState(value != 'disabled');
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
SettingsListener.observe('debug.log-animations.enabled', false, function(value) {
|
||||
Services.prefs.setBoolPref('layers.offmainthreadcomposition.log-animations', value);
|
||||
});
|
||||
|
|
|
@ -1031,6 +1031,7 @@ let IndexedDBPromptHelper = {
|
|||
let RemoteDebugger = {
|
||||
_promptDone: false,
|
||||
_promptAnswer: false,
|
||||
_running: false,
|
||||
|
||||
prompt: function debugger_prompt() {
|
||||
this._promptDone = false;
|
||||
|
@ -1051,8 +1052,21 @@ let RemoteDebugger = {
|
|||
this._promptDone = true;
|
||||
},
|
||||
|
||||
get isDebugging() {
|
||||
if (!this._running) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DebuggerServer._connections &&
|
||||
Object.keys(DebuggerServer._connections).length > 0;
|
||||
},
|
||||
|
||||
// Start the debugger server.
|
||||
start: function debugger_start() {
|
||||
if (this._running) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
// Ask for remote connections.
|
||||
DebuggerServer.init(this.prompt.bind(this));
|
||||
|
@ -1088,13 +1102,20 @@ let RemoteDebugger = {
|
|||
"/data/local/debugger-socket";
|
||||
try {
|
||||
DebuggerServer.openListener(path);
|
||||
this._running = true;
|
||||
} catch (e) {
|
||||
dump('Unable to start debugger server: ' + e + '\n');
|
||||
}
|
||||
},
|
||||
|
||||
stop: function debugger_stop() {
|
||||
if (!this._running) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
// Can this really happen if we are running?
|
||||
this._running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1103,6 +1124,7 @@ let RemoteDebugger = {
|
|||
} catch (e) {
|
||||
dump('Unable to stop debugger server: ' + e + '\n');
|
||||
}
|
||||
this._running = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "3b850fa17c888bdd31f1a163fd7b92f6f020449d",
|
||||
"revision": "6e971c6a9f947d301a0401fcbc87141b8eba23b6",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ class MachCommands(MachCommandBase):
|
|||
valgrind,
|
||||
'--error-exitcode=1',
|
||||
'--smc-check=all-non-file',
|
||||
'--vex-iropt-register-updates=allregs-at-each-insn',
|
||||
'--vex-iropt-register-updates=allregs-at-mem-access',
|
||||
'--gen-suppressions=all',
|
||||
'--num-callers=20',
|
||||
'--leak-check=full',
|
||||
|
|
|
@ -738,7 +738,13 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
|
|||
if (!mUrlString.IsEmpty() && mIsAnchor) {
|
||||
nsAutoString dragData(mUrlString);
|
||||
dragData.AppendLiteral("\n");
|
||||
dragData += mTitleString;
|
||||
// Remove leading and trailing newlines in the title and replace them with
|
||||
// space in remaining positions - they confuse PlacesUtils::unwrapNodes
|
||||
// that expects url\ntitle formatted data for x-moz-url.
|
||||
nsAutoString title(mTitleString);
|
||||
title.Trim("\r\n");
|
||||
title.ReplaceChar("\r\n", ' ');
|
||||
dragData += title;
|
||||
|
||||
AddString(aDataTransfer, NS_LITERAL_STRING(kURLMime), dragData, principal);
|
||||
AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
|
@ -2795,6 +2796,16 @@ nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
continue;
|
||||
}
|
||||
|
||||
// Don't scroll vertically by mouse-wheel on a single-line text control.
|
||||
if (checkIfScrollableY) {
|
||||
nsIContent* c = scrollFrame->GetContent();
|
||||
nsCOMPtr<nsITextControlElement> ctrl =
|
||||
do_QueryInterface(c->IsInAnonymousSubtree() ? c->GetBindingParent() : c);
|
||||
if (ctrl && ctrl->IsSingleLineTextControl()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkIfScrollableX && !checkIfScrollableY) {
|
||||
return frameToScroll;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ skip-if = true # Disabled due to timeouts.
|
|||
[test_bug944847.html]
|
||||
skip-if = toolkit == "gonk"
|
||||
[test_bug944011.html]
|
||||
[test_bug946632.html]
|
||||
[test_clickevent_on_input.html]
|
||||
[test_continuous_wheel_events.html]
|
||||
[test_dblclick_explicit_original_target.html]
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=946632
|
||||
-->
|
||||
<head>
|
||||
<title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
.scrollable {
|
||||
overflow: scroll;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
input {
|
||||
font-size: 72px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946632">Mozilla Bug 946632</a>
|
||||
<p id="display"></p>
|
||||
<div id="container" class="scrollable">
|
||||
<input value="value">
|
||||
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTests, window);
|
||||
|
||||
var input = document.querySelector("input");
|
||||
var container = document.querySelector("#container");
|
||||
|
||||
function prepare(check)
|
||||
{
|
||||
container.scrollTop = 0;
|
||||
container.scrollLeft = 0;
|
||||
input.scrollTop = 0;
|
||||
input.scrollLeft = 0;
|
||||
container.style.display='none';
|
||||
container.getBoundingClientRect();
|
||||
container.style.display='';
|
||||
container.getBoundingClientRect();
|
||||
scrollHandler = function(event) {
|
||||
window.removeEventListener("scroll", arguments.callee, true);
|
||||
event.stopPropagation();
|
||||
check(event)
|
||||
setTimeout(nextTest,0);
|
||||
};
|
||||
window.addEventListener("scroll", scrollHandler, true);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{
|
||||
check: function(event) {
|
||||
is(event.target, container, "<input> vertical line scroll targets container");
|
||||
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
|
||||
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
|
||||
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
|
||||
is(input.scrollLeft, 0, "<input> horizontal line scroll input.scrollLeft");
|
||||
},
|
||||
test: function() {
|
||||
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
|
||||
deltaY: 1.0, lineOrPageDeltaY: 1 });
|
||||
}
|
||||
},
|
||||
{
|
||||
check: function(event) {
|
||||
is(event.target, input, "<input> horizontal line scroll targets <input>");
|
||||
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
|
||||
ok(input.scrollLeft > 0, "<input> horizontal line scroll input.scrollLeft");
|
||||
is(container.scrollTop, 0, "<input> horizontal line scroll container.scrollTop");
|
||||
is(container.scrollLeft, 0, "<input> horizontal line scroll container.scrollLeft");
|
||||
},
|
||||
test: function() {
|
||||
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
|
||||
deltaX: 1.0, lineOrPageDeltaX: 1 });
|
||||
}
|
||||
},
|
||||
{
|
||||
check: function(event) {
|
||||
is(event.target, container, "<input> vertical page scroll targets container");
|
||||
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
|
||||
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
|
||||
is(input.scrollTop, 0, "<input> vertical page scroll input.scrollTop");
|
||||
is(input.scrollLeft, 0, "<input> vertical page scroll input.scrollLeft");
|
||||
},
|
||||
test: function() {
|
||||
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
|
||||
deltaY: 1.0, lineOrPageDeltaY: 1 });
|
||||
}
|
||||
},
|
||||
{
|
||||
check: function(event) {
|
||||
is(event.target, input, "<input> horizontal page scroll targets <input>");
|
||||
is(input.scrollTop, 0, "<input> horizontal page scroll input.scrollTop");
|
||||
ok(input.scrollLeft > 0, "<input> horizontal page scroll input.scrollLeft");
|
||||
is(container.scrollTop, 0, "<input> horizontal page scroll container.scrollTop");
|
||||
is(container.scrollLeft, 0, "<input> horizontal page scroll container.scrollLeft");
|
||||
},
|
||||
test: function() {
|
||||
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
|
||||
deltaX: 1.0, lineOrPageDeltaX: 1 });
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var i = 0;
|
||||
function nextTest()
|
||||
{
|
||||
if (i == tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
var test = tests[i];
|
||||
++i;
|
||||
prepare(test.check);
|
||||
test.test();
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
nextTest();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -152,7 +152,13 @@ static const char* GetOmxLibraryName()
|
|||
return nullptr;
|
||||
|
||||
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
|
||||
if (version == 13 || version == 12 || version == 11) {
|
||||
/*
|
||||
if (version >= 19) {
|
||||
*/
|
||||
if (version >= 16) {
|
||||
return "libomxpluginkk.so";
|
||||
}
|
||||
else if (version == 13 || version == 12 || version == 11) {
|
||||
return "libomxpluginhc.so";
|
||||
}
|
||||
else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) {
|
||||
|
@ -180,7 +186,7 @@ static const char* GetOmxLibraryName()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Default libomxplugin for non-gingerbread devices
|
||||
// Ice Cream Sandwich and Jellybean
|
||||
return "libomxplugin.so";
|
||||
|
||||
#elif defined(ANDROID) && defined(MOZ_WIDGET_GONK)
|
||||
|
|
|
@ -198,6 +198,7 @@ function createDOMDownloadObject(aWindow, aDownload) {
|
|||
|
||||
function DOMDownloadImpl() {
|
||||
debug("DOMDownloadImpl constructor ");
|
||||
|
||||
this.wrappedJSObject = this;
|
||||
this.totalBytes = 0;
|
||||
this.currentBytes = 0;
|
||||
|
@ -205,8 +206,10 @@ function DOMDownloadImpl() {
|
|||
this.path = null;
|
||||
this.state = "stopped";
|
||||
this.contentType = null;
|
||||
this.startTime = Date.now();
|
||||
this.error = null;
|
||||
|
||||
/* fields that require getters/setters */
|
||||
this._error = null;
|
||||
this._startTime = new Date();
|
||||
|
||||
/* private fields */
|
||||
this.id = null;
|
||||
|
@ -244,6 +247,27 @@ DOMDownloadImpl.prototype = {
|
|||
return this.__DOM_IMPL__.getEventHandler("onstatechange");
|
||||
},
|
||||
|
||||
get error() {
|
||||
return this._error;
|
||||
},
|
||||
|
||||
set error(aError) {
|
||||
this._error = aError;
|
||||
},
|
||||
|
||||
get startTime() {
|
||||
return this._startTime;
|
||||
},
|
||||
|
||||
set startTime(aStartTime) {
|
||||
if (aStartTime instanceof Date) {
|
||||
this._startTime = aStartTime;
|
||||
}
|
||||
else {
|
||||
this._startTime = new Date(aStartTime);
|
||||
}
|
||||
},
|
||||
|
||||
_init: function(aWindow, aDownload) {
|
||||
this._window = aWindow;
|
||||
this.id = aDownload.id;
|
||||
|
|
|
@ -24,6 +24,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=938023
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var index = -1;
|
||||
var todayDate = new Date();
|
||||
var baseServeURL = "http://mochi.test:8888/tests/dom/downloads/tests/";
|
||||
var baseDownloadPath = "/mnt/sdcard/downloads/";
|
||||
var lastKnownCurrentBytes = 0;
|
||||
|
||||
function next() {
|
||||
index += 1;
|
||||
|
@ -38,16 +42,54 @@ function next() {
|
|||
}
|
||||
}
|
||||
|
||||
function checkConsistentDownloadAttributes(download) {
|
||||
var href = document.getElementById("download1").getAttribute("href");
|
||||
var expectedServeURL = baseServeURL + href;
|
||||
var expectedDownloadPath = baseDownloadPath + "test.bin";
|
||||
|
||||
// bug 945323: Download path isn't honoring download attribute
|
||||
todo(download.path === expectedDownloadPath,
|
||||
"Download path = " + expectedDownloadPath);
|
||||
|
||||
ok(download.startTime >= todayDate,
|
||||
"Download start time should be greater than or equal to today");
|
||||
|
||||
is(download.error, null, "Download does not have an error");
|
||||
|
||||
is(download.url, expectedServeURL,
|
||||
"Download URL = " + expectedServeURL);
|
||||
ok(download.id !== null, "Download id is defined");
|
||||
is(download.contentType, "application/octet-stream",
|
||||
"Download content type is application/octet-stream");
|
||||
}
|
||||
|
||||
function downloadChange(evt) {
|
||||
var download = evt.download;
|
||||
if (download.state == "succeeded") {
|
||||
ok(download.totalBytes == 1024, "Download size is 1024 bytes.");
|
||||
ok(download.contentType == "application/octet-stream",
|
||||
"contentType is application/octet-stream.");
|
||||
checkConsistentDownloadAttributes(download);
|
||||
is(download.totalBytes, 1024, "Download total size is 1024 bytes");
|
||||
|
||||
if (download.state === "succeeded") {
|
||||
is(download.currentBytes, 1024, "Download current size is 1024 bytes");
|
||||
SimpleTest.finish();
|
||||
} else if (download.state === "downloading") {
|
||||
ok(download.currentBytes > lastKnownCurrentBytes,
|
||||
"Download current size is larger than last download change event");
|
||||
lastKnownCurrentBytes = download.currentBytes;
|
||||
} else {
|
||||
ok(false, "Unexpected download state = " + download.state);
|
||||
}
|
||||
}
|
||||
|
||||
function downloadStart(evt) {
|
||||
var download = evt.download;
|
||||
checkConsistentDownloadAttributes(download);
|
||||
|
||||
is(download.currentBytes, 0, "Download current size is zero");
|
||||
is(download.state, "downloading", "Download state is downloading");
|
||||
|
||||
download.onstatechange = downloadChange;
|
||||
}
|
||||
|
||||
var steps = [
|
||||
// Start by setting the pref to true.
|
||||
function() {
|
||||
|
@ -61,11 +103,7 @@ var steps = [
|
|||
SpecialPowers.pushPermissions([
|
||||
{type: "downloads", allow: true, context: document}
|
||||
], function() {
|
||||
navigator.mozDownloadManager.ondownloadstart =
|
||||
function(evt) {
|
||||
ok(true, "Download started");
|
||||
evt.download.addEventListener("statechange", downloadChange);
|
||||
}
|
||||
navigator.mozDownloadManager.ondownloadstart = downloadStart;
|
||||
next();
|
||||
});
|
||||
},
|
||||
|
@ -82,3 +120,4 @@ next();
|
|||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ IndexedDBParent::CloneProtocol(Channel* aChannel,
|
|||
|
||||
bool
|
||||
IndexedDBParent::CheckPermissionInternal(const nsAString& aDatabaseName,
|
||||
const nsDependentCString& aPermission)
|
||||
const nsACString& aPermission)
|
||||
{
|
||||
MOZ_ASSERT(!mASCIIOrigin.IsEmpty());
|
||||
MOZ_ASSERT(mManagerContent || mManagerTab);
|
||||
|
|
|
@ -201,7 +201,7 @@ public:
|
|||
protected:
|
||||
bool
|
||||
CheckPermissionInternal(const nsAString& aDatabaseName,
|
||||
const nsDependentCString& aPermission);
|
||||
const nsACString& aPermission);
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
|
|
@ -611,7 +611,7 @@ TabChild::HandlePossibleViewportChange()
|
|||
// The page must have been refreshed in some way such as a new document or
|
||||
// new CSS viewport, so we know that there's no velocity, acceleration, and
|
||||
// we have no idea how long painting will take.
|
||||
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
|
||||
metrics, ScreenPoint(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
|
||||
metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
// This is the root layer, so the cumulative resolution is the same
|
||||
// as the resolution.
|
||||
|
|
|
@ -754,6 +754,16 @@ static SourceSet *
|
|||
class GetUserMediaRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* GetUserMediaRunnable is meant for dispatch off main thread, where it would
|
||||
* be illegal to free JS callbacks. Therefore, it uses a rather risky strategy
|
||||
* of holding "already_AddRefed" references to the JS callbacks that must be
|
||||
* transfered and released in consequent dispatches arriving on main thread.
|
||||
*
|
||||
* A special Arm() method must be called before dispatch to enable this
|
||||
* behavior, because GetUserMediaRunnables are held in other circumstances.
|
||||
*/
|
||||
|
||||
GetUserMediaRunnable(
|
||||
const MediaStreamConstraintsInternal& aConstraints,
|
||||
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
|
||||
|
@ -761,8 +771,10 @@ public:
|
|||
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
|
||||
MediaEnginePrefs &aPrefs)
|
||||
: mConstraints(aConstraints)
|
||||
, mSuccess(aSuccess)
|
||||
, mError(aError)
|
||||
, mSuccess(nullptr)
|
||||
, mError(nullptr)
|
||||
, mSuccessHolder(aSuccess)
|
||||
, mErrorHolder(aError)
|
||||
, mWindowID(aWindowID)
|
||||
, mListener(aListener)
|
||||
, mPrefs(aPrefs)
|
||||
|
@ -783,8 +795,10 @@ public:
|
|||
MediaEnginePrefs &aPrefs,
|
||||
MediaEngine* aBackend)
|
||||
: mConstraints(aConstraints)
|
||||
, mSuccess(aSuccess)
|
||||
, mError(aError)
|
||||
, mSuccess(nullptr)
|
||||
, mError(nullptr)
|
||||
, mSuccessHolder(aSuccess)
|
||||
, mErrorHolder(aError)
|
||||
, mWindowID(aWindowID)
|
||||
, mListener(aListener)
|
||||
, mPrefs(aPrefs)
|
||||
|
@ -800,10 +814,24 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Once "armed", GetUserMediaRunnable will leak its JS callbacks if destroyed.
|
||||
* Arm() must be called before the runnable can be dispatched or used, and the
|
||||
* runnable must be dispatched or used once armed. Callbacks get released on
|
||||
* the main thread at the runnable's completion.
|
||||
*/
|
||||
void
|
||||
Arm() {
|
||||
mSuccess = mSuccessHolder.forget();
|
||||
mError = mErrorHolder.forget();
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||
MOZ_ASSERT(mSuccess.mRawPtr);
|
||||
MOZ_ASSERT(mError.mRawPtr);
|
||||
|
||||
// Was a backend provided?
|
||||
if (!mBackendChosen) {
|
||||
|
@ -842,8 +870,11 @@ public:
|
|||
nsresult
|
||||
Denied(const nsAString& aErrorMsg)
|
||||
{
|
||||
// We add a disabled listener to the StreamListeners array until accepted
|
||||
// If this was the only active MediaStream, remove the window from the list.
|
||||
MOZ_ASSERT(mSuccess.mRawPtr);
|
||||
MOZ_ASSERT(mError.mRawPtr);
|
||||
|
||||
// We add a disabled listener to the StreamListeners array until accepted
|
||||
// If this was the only active MediaStream, remove the window from the list.
|
||||
if (NS_IsMainThread()) {
|
||||
// This is safe since we're on main-thread, and the window can only
|
||||
// be invalidated from the main-thread (see OnNavigation)
|
||||
|
@ -886,6 +917,8 @@ public:
|
|||
nsresult
|
||||
SelectDevice()
|
||||
{
|
||||
MOZ_ASSERT(mSuccess.mRawPtr);
|
||||
MOZ_ASSERT(mError.mRawPtr);
|
||||
if (mConstraints.mPicture || mConstraints.mVideo) {
|
||||
ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
|
||||
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
|
||||
|
@ -924,6 +957,8 @@ public:
|
|||
void
|
||||
ProcessGetUserMedia(MediaEngineSource* aAudioSource, MediaEngineSource* aVideoSource)
|
||||
{
|
||||
MOZ_ASSERT(mSuccess.mRawPtr);
|
||||
MOZ_ASSERT(mError.mRawPtr);
|
||||
nsresult rv;
|
||||
if (aAudioSource) {
|
||||
rv = aAudioSource->Allocate(mPrefs);
|
||||
|
@ -962,6 +997,8 @@ public:
|
|||
void
|
||||
ProcessGetUserMediaSnapshot(MediaEngineSource* aSource, int aDuration)
|
||||
{
|
||||
MOZ_ASSERT(mSuccess.mRawPtr);
|
||||
MOZ_ASSERT(mError.mRawPtr);
|
||||
nsresult rv = aSource->Allocate(mPrefs);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_DispatchToMainThread(new ErrorCallbackRunnable(
|
||||
|
@ -988,6 +1025,8 @@ private:
|
|||
|
||||
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
|
||||
already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
|
||||
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccessHolder;
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mErrorHolder;
|
||||
uint64_t mWindowID;
|
||||
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
|
||||
nsRefPtr<MediaDevice> mAudioDevice;
|
||||
|
@ -1296,7 +1335,6 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
|
|||
// Store the WindowID in a hash table and mark as active. The entry is removed
|
||||
// when this window is closed or navigated away from.
|
||||
uint64_t windowID = aWindow->WindowID();
|
||||
nsRefPtr<GetUserMediaRunnable> gUMRunnable;
|
||||
// This is safe since we're on main-thread, and the windowlist can only
|
||||
// be invalidated from the main-thread (see OnNavigation)
|
||||
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
|
||||
|
@ -1340,17 +1378,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
|
|||
c.mVideo = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass runnables along to GetUserMediaRunnable so it can add the
|
||||
* MediaStreamListener to the runnable list.
|
||||
*/
|
||||
// Pass callbacks and MediaStreamListener along to GetUserMediaRunnable.
|
||||
nsRefPtr<GetUserMediaRunnable> runnable;
|
||||
if (c.mFake) {
|
||||
// Fake stream from default backend.
|
||||
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
|
||||
runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
|
||||
onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
|
||||
} else {
|
||||
// Stream from default device from WebRTC backend.
|
||||
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
|
||||
runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
|
||||
onError.forget(), windowID, listener, mPrefs);
|
||||
}
|
||||
|
||||
|
@ -1363,13 +1399,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
|
|||
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
|
||||
if (c.mPicture) {
|
||||
// ShowFilePickerForMimeType() must run on the Main Thread! (on Android)
|
||||
NS_DispatchToMainThread(gUMRunnable);
|
||||
runnable->Arm();
|
||||
NS_DispatchToMainThread(runnable);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
// XXX No full support for picture in Desktop yet (needs proper UI)
|
||||
if (aPrivileged || c.mFake) {
|
||||
mMediaThread->Dispatch(gUMRunnable, NS_DISPATCH_NORMAL);
|
||||
runnable->Arm();
|
||||
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
// Ask for user permission, and dispatch runnable (or not) when a response
|
||||
// is received via an observer notification. Each call is paired with its
|
||||
|
@ -1388,9 +1426,18 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
|
|||
id.ToProvidedString(buffer);
|
||||
NS_ConvertUTF8toUTF16 callID(buffer);
|
||||
|
||||
// Store the current callback.
|
||||
mActiveCallbacks.Put(callID, gUMRunnable);
|
||||
// Store the current unarmed runnable w/callbacks.
|
||||
mActiveCallbacks.Put(callID, runnable);
|
||||
|
||||
// Add a WindowID cross-reference so OnNavigation can tear things down
|
||||
nsTArray<nsString>* array;
|
||||
if (!mCallIds.Get(windowID, &array)) {
|
||||
array = new nsTArray<nsString>();
|
||||
array->AppendElement(callID);
|
||||
mCallIds.Put(windowID, array);
|
||||
} else {
|
||||
array->AppendElement(callID);
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
nsRefPtr<GetUserMediaRequest> req = new GetUserMediaRequest(aWindow,
|
||||
callID, c);
|
||||
|
@ -1471,6 +1518,14 @@ MediaManager::OnNavigation(uint64_t aWindowID)
|
|||
// Invalidate this window. The runnables check this value before making
|
||||
// a call to content.
|
||||
|
||||
nsTArray<nsString>* callIds;
|
||||
if (mCallIds.Get(aWindowID, &callIds)) {
|
||||
for (int i = 0, len = callIds->Length(); i < len; ++i) {
|
||||
mActiveCallbacks.Remove((*callIds)[i]);
|
||||
}
|
||||
mCallIds.Remove(aWindowID);
|
||||
}
|
||||
|
||||
// This is safe since we're on main-thread, and the windowlist can only
|
||||
// be added to from the main-thread
|
||||
StreamListeners* listeners = GetWindowListeners(aWindowID);
|
||||
|
@ -1606,6 +1661,7 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
MutexAutoLock lock(mMutex);
|
||||
GetActiveWindows()->Clear();
|
||||
mActiveCallbacks.Clear();
|
||||
mCallIds.Clear();
|
||||
LOG(("Releasing MediaManager singleton and thread"));
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
@ -1614,25 +1670,24 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
|
||||
} else if (!strcmp(aTopic, "getUserMedia:response:allow")) {
|
||||
nsString key(aData);
|
||||
nsRefPtr<nsRunnable> runnable;
|
||||
nsRefPtr<GetUserMediaRunnable> runnable;
|
||||
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
|
||||
return NS_OK;
|
||||
}
|
||||
mActiveCallbacks.Remove(key);
|
||||
runnable->Arm();
|
||||
|
||||
if (aSubject) {
|
||||
// A particular device or devices were chosen by the user.
|
||||
// NOTE: does not allow setting a device to null; assumes nullptr
|
||||
GetUserMediaRunnable* gUMRunnable =
|
||||
static_cast<GetUserMediaRunnable*>(runnable.get());
|
||||
|
||||
nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
|
||||
MOZ_ASSERT(array);
|
||||
uint32_t len = 0;
|
||||
array->Count(&len);
|
||||
MOZ_ASSERT(len);
|
||||
if (!len) {
|
||||
gUMRunnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED")); // neither audio nor video were selected
|
||||
// neither audio nor video were selected
|
||||
runnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
|
||||
return NS_OK;
|
||||
}
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
|
@ -1644,9 +1699,9 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
nsString type;
|
||||
device->GetType(type);
|
||||
if (type.EqualsLiteral("video")) {
|
||||
gUMRunnable->SetVideoDevice(static_cast<MediaDevice*>(device.get()));
|
||||
runnable->SetVideoDevice(static_cast<MediaDevice*>(device.get()));
|
||||
} else if (type.EqualsLiteral("audio")) {
|
||||
gUMRunnable->SetAudioDevice(static_cast<MediaDevice*>(device.get()));
|
||||
runnable->SetAudioDevice(static_cast<MediaDevice*>(device.get()));
|
||||
} else {
|
||||
NS_WARNING("Unknown device type in getUserMedia");
|
||||
}
|
||||
|
@ -1670,15 +1725,13 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
}
|
||||
|
||||
nsString key(aData);
|
||||
nsRefPtr<nsRunnable> runnable;
|
||||
nsRefPtr<GetUserMediaRunnable> runnable;
|
||||
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
|
||||
return NS_OK;
|
||||
}
|
||||
mActiveCallbacks.Remove(key);
|
||||
|
||||
GetUserMediaRunnable* gUMRunnable =
|
||||
static_cast<GetUserMediaRunnable*>(runnable.get());
|
||||
gUMRunnable->Denied(errorMessage);
|
||||
runnable->Arm();
|
||||
runnable->Denied(errorMessage);
|
||||
return NS_OK;
|
||||
|
||||
} else if (!strcmp(aTopic, "getUserMedia:revoke")) {
|
||||
|
|
|
@ -241,6 +241,7 @@ typedef enum {
|
|||
} MediaOperation;
|
||||
|
||||
class MediaManager;
|
||||
class GetUserMediaRunnable;
|
||||
|
||||
/**
|
||||
* Send an error back to content. The error is the form a string.
|
||||
|
@ -524,7 +525,8 @@ private:
|
|||
|
||||
// ONLY access from MainThread so we don't need to lock
|
||||
WindowTable mActiveWindows;
|
||||
nsRefPtrHashtable<nsStringHashKey, nsRunnable> mActiveCallbacks;
|
||||
nsRefPtrHashtable<nsStringHashKey, GetUserMediaRunnable> mActiveCallbacks;
|
||||
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
|
||||
// Always exists
|
||||
nsCOMPtr<nsIThread> mMediaThread;
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ class nsGeolocationRequest
|
|||
void SendLocation(nsIDOMGeoPosition* location);
|
||||
bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
|
||||
void SetTimeoutTimer();
|
||||
void StopTimeoutTimer();
|
||||
void NotifyErrorAndShutdown(uint16_t);
|
||||
nsIPrincipal* GetPrincipal();
|
||||
|
||||
|
@ -348,6 +349,7 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
|
|||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::Notify(nsITimer* aTimer)
|
||||
{
|
||||
StopTimeoutTimer();
|
||||
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -363,10 +365,6 @@ nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
|
|||
}
|
||||
|
||||
NotifyError(aErrorCode);
|
||||
|
||||
if (!mShutdown) {
|
||||
SetTimeoutTimer();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -475,10 +473,7 @@ nsGeolocationRequest::Allow()
|
|||
void
|
||||
nsGeolocationRequest::SetTimeoutTimer()
|
||||
{
|
||||
if (mTimeoutTimer) {
|
||||
mTimeoutTimer->Cancel();
|
||||
mTimeoutTimer = nullptr;
|
||||
}
|
||||
StopTimeoutTimer();
|
||||
|
||||
int32_t timeout;
|
||||
if (mOptions && (timeout = mOptions->mTimeout) != 0) {
|
||||
|
@ -494,6 +489,15 @@ nsGeolocationRequest::SetTimeoutTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationRequest::StopTimeoutTimer()
|
||||
{
|
||||
if (mTimeoutTimer) {
|
||||
mTimeoutTimer->Cancel();
|
||||
mTimeoutTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
|
||||
{
|
||||
|
@ -539,12 +543,9 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
|
|||
callback->HandleEvent(aPosition);
|
||||
}
|
||||
|
||||
if (!mShutdown) {
|
||||
// For watch requests, the handler may have called clearWatch
|
||||
MOZ_ASSERT(mIsWatchPositionRequest,
|
||||
"non-shutdown getCurrentPosition request after callback!");
|
||||
SetTimeoutTimer();
|
||||
}
|
||||
StopTimeoutTimer();
|
||||
MOZ_ASSERT(mShutdown || mIsWatchPositionRequest,
|
||||
"non-shutdown getCurrentPosition request after callback!");
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
|
@ -564,6 +565,16 @@ nsGeolocationRequest::Update(nsIDOMGeoPosition* aPosition)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::LocationUpdatePending()
|
||||
{
|
||||
if (!mTimeoutTimer) {
|
||||
SetTimeoutTimer();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -809,6 +820,16 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::LocationUpdatePending()
|
||||
{
|
||||
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
|
||||
mGeolocators[i]->LocationUpdatePending();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -1130,6 +1151,17 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Geolocation::LocationUpdatePending()
|
||||
{
|
||||
// this event is only really interesting for watch callbacks
|
||||
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
|
||||
mWatchingCallbacks[i]->LocationUpdatePending();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Geolocation::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
|
|
@ -143,6 +143,9 @@ WifiGeoPositionProvider.prototype = {
|
|||
LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
|
||||
this.hasSeenWiFi = true;
|
||||
|
||||
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
|
||||
.locationUpdatePending();
|
||||
|
||||
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
|
||||
|
||||
function isPublic(ap) {
|
||||
|
|
|
@ -24,16 +24,16 @@ class CoreLocationObjects;
|
|||
|
||||
class CoreLocationLocationProvider
|
||||
: public nsIGeolocationProvider
|
||||
, public nsIGeolocationUpdate
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIGEOLOCATIONUPDATE
|
||||
NS_DECL_NSIGEOLOCATIONPROVIDER
|
||||
|
||||
CoreLocationLocationProvider();
|
||||
static bool IsCoreLocationAvailable();
|
||||
|
||||
void NotifyError(uint16_t aErrorCode);
|
||||
void Update(nsIDOMGeoPosition* aSomewhere);
|
||||
private:
|
||||
virtual ~CoreLocationLocationProvider() {};
|
||||
|
||||
|
|
|
@ -218,19 +218,16 @@ CoreLocationLocationProvider::SetHighAccuracy(bool aEnable)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere)
|
||||
{
|
||||
if (aSomewhere && mCallback) {
|
||||
mCallback->Update(aSomewhere);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
mCallback->NotifyError(aErrorCode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ interface DOMDownload : EventTarget {
|
|||
|
||||
// A DOM error object, that will be not null when a download is stopped
|
||||
// because something failed.
|
||||
readonly attribute DOMError error;
|
||||
readonly attribute DOMError? error;
|
||||
|
||||
// Pauses the download.
|
||||
Promise pause();
|
||||
|
|
|
@ -502,6 +502,16 @@ _cairo_win32_surface_finish (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
get_d3d9_dc_and_clear_clip (cairo_win32_surface_t *surface)
|
||||
{
|
||||
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
|
||||
// The DC that we get back from the surface will not have
|
||||
// a clip so clear surface->clip_region so that we don't think we have
|
||||
// one when we don't.
|
||||
_cairo_win32_surface_set_clip_region (surface, NULL);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
|
||||
int x,
|
||||
|
@ -521,7 +531,7 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
|
|||
&rectout, &rectin, 0);
|
||||
surface->dc = 0; // Don't use the DC when this is locked!
|
||||
if (hr) {
|
||||
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
|
||||
get_d3d9_dc_and_clear_clip (surface);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
local = cairo_image_surface_create_for_data (rectout.pBits,
|
||||
|
@ -530,12 +540,12 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
|
|||
rectout.Pitch);
|
||||
if (local == NULL) {
|
||||
IDirect3DSurface9_UnlockRect (surface->d3d9surface);
|
||||
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
|
||||
get_d3d9_dc_and_clear_clip (surface);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
if (local->base.status) {
|
||||
IDirect3DSurface9_UnlockRect (surface->d3d9surface);
|
||||
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
|
||||
get_d3d9_dc_and_clear_clip (surface);
|
||||
return local->base.status;
|
||||
}
|
||||
|
||||
|
@ -709,7 +719,7 @@ _cairo_win32_surface_release_source_image (void *abstract_surf
|
|||
|
||||
if (local && local->d3d9surface) {
|
||||
IDirect3DSurface9_UnlockRect (local->d3d9surface);
|
||||
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
|
||||
get_d3d9_dc_and_clear_clip (surface);
|
||||
cairo_surface_destroy ((cairo_surface_t *)image);
|
||||
} else {
|
||||
cairo_surface_destroy ((cairo_surface_t *)local);
|
||||
|
@ -784,7 +794,7 @@ _cairo_win32_surface_release_dest_image (void *abstract_surfa
|
|||
|
||||
if (local->d3d9surface) {
|
||||
IDirect3DSurface9_UnlockRect (local->d3d9surface);
|
||||
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
|
||||
get_d3d9_dc_and_clear_clip (surface);
|
||||
cairo_surface_destroy ((cairo_surface_t *)image);
|
||||
} else {
|
||||
|
||||
|
|
|
@ -154,8 +154,6 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
|
|||
if (aOperator == OP_SOURCE) {
|
||||
aTarget->PopClip();
|
||||
}
|
||||
|
||||
aTarget->Flush();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -391,6 +389,17 @@ ComputeBufferRect(const nsIntRect& aRequestedRect)
|
|||
return rect;
|
||||
}
|
||||
|
||||
void
|
||||
RotatedContentBuffer::FlushBuffers()
|
||||
{
|
||||
if (mDTBuffer) {
|
||||
mDTBuffer->Flush();
|
||||
}
|
||||
if (mDTBufferOnWhite) {
|
||||
mDTBufferOnWhite->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
RotatedContentBuffer::PaintState
|
||||
RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags)
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
|
||||
BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
|
||||
};
|
||||
// It is the callers repsonsibility to ensure aTarget is flushed after calling
|
||||
// this method.
|
||||
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
|
||||
float aOpacity = 1.0,
|
||||
gfx::CompositionOp aOperator = gfx::OP_OVER,
|
||||
|
@ -396,6 +398,10 @@ protected:
|
|||
*/
|
||||
bool EnsureBuffer();
|
||||
bool EnsureBufferOnWhite();
|
||||
|
||||
// Flush our buffers if they are mapped.
|
||||
void FlushBuffers();
|
||||
|
||||
/**
|
||||
* True if we have a buffer where we can get it (but not necessarily
|
||||
* mapped currently).
|
||||
|
|
|
@ -598,6 +598,8 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
|
|||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
// We need to flush our buffers before we unlock our front textures
|
||||
FlushBuffers();
|
||||
mFrontClient->Unlock();
|
||||
if (mFrontClientOnWhite) {
|
||||
mFrontClientOnWhite->Unlock();
|
||||
|
@ -816,6 +818,9 @@ DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
|
|||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
|
||||
// We need to flush our buffers before we unlock our front textures
|
||||
FlushBuffers();
|
||||
|
||||
mFrontAndBackBufferDiffer = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,10 +168,10 @@ static int32_t gPanRepaintInterval = 250;
|
|||
static int32_t gFlingRepaintInterval = 75;
|
||||
|
||||
/**
|
||||
* Minimum amount of speed along an axis before we begin painting far ahead by
|
||||
* adjusting the displayport.
|
||||
* Minimum amount of speed along an axis before we switch to "skate" multipliers
|
||||
* rather than using the "stationary" multipliers.
|
||||
*/
|
||||
static float gMinSkateSpeed = 0.7f;
|
||||
static float gMinSkateSpeed = 1.0f;
|
||||
|
||||
/**
|
||||
* Duration of a zoom to animation.
|
||||
|
@ -207,22 +207,26 @@ static int gTouchListenerTimeout = 300;
|
|||
*/
|
||||
static int gNumPaintDurationSamples = 3;
|
||||
|
||||
/** The multiplier we apply to a dimension's length if it is skating. That is,
|
||||
* if it's going above sMinSkateSpeed. We prefer to increase the size of the
|
||||
/**
|
||||
* The multiplier we apply to the displayport size if it is skating (current
|
||||
* velocity is above gMinSkateSpeed). We prefer to increase the size of the
|
||||
* Y axis because it is more natural in the case that a user is reading a page
|
||||
* that scrolls up/down. Note that one, both or neither of these may be used
|
||||
* at any instant.
|
||||
* In general we want g[XY]SkateSizeMultiplier to be smaller than the corresponding
|
||||
* stationary size multiplier because when panning fast we would like to paint
|
||||
* less and get faster, more predictable paint times. When panning slowly we
|
||||
* can afford to paint more even though it's slower.
|
||||
*/
|
||||
static float gXSkateSizeMultiplier = 3.0f;
|
||||
static float gYSkateSizeMultiplier = 3.5f;
|
||||
static float gXSkateSizeMultiplier = 1.5f;
|
||||
static float gYSkateSizeMultiplier = 2.5f;
|
||||
|
||||
/** The multiplier we apply to a dimension's length if it is stationary. We
|
||||
* prefer to increase the size of the Y axis because it is more natural in the
|
||||
* case that a user is reading a page that scrolls up/down. Note that one,
|
||||
* both or neither of these may be used at any instant.
|
||||
/**
|
||||
* The multiplier we apply to the displayport size if it is not skating (see
|
||||
* documentation for gXSkateSizeMultiplier).
|
||||
*/
|
||||
static float gXStationarySizeMultiplier = 1.5f;
|
||||
static float gYStationarySizeMultiplier = 2.5f;
|
||||
static float gXStationarySizeMultiplier = 3.0f;
|
||||
static float gYStationarySizeMultiplier = 3.5f;
|
||||
|
||||
/**
|
||||
* The time period in ms that throttles mozbrowserasyncscroll event.
|
||||
|
@ -931,8 +935,8 @@ float AsyncPanZoomController::PanDistance() {
|
|||
return NS_hypot(mX.PanDistance(), mY.PanDistance());
|
||||
}
|
||||
|
||||
const gfx::Point AsyncPanZoomController::GetVelocityVector() {
|
||||
return gfx::Point(mX.GetVelocity(), mY.GetVelocity());
|
||||
const ScreenPoint AsyncPanZoomController::GetVelocityVector() {
|
||||
return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
|
||||
}
|
||||
|
||||
const gfx::Point AsyncPanZoomController::GetAccelerationVector() {
|
||||
|
@ -1159,103 +1163,65 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale,
|
|||
mFrameMetrics.mScrollOffset = (mFrameMetrics.mScrollOffset + aFocus) - (aFocus / aScale);
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier,
|
||||
double aEstimatedPaintDuration,
|
||||
float aCompositionBounds,
|
||||
float aVelocity,
|
||||
float aAcceleration,
|
||||
float* aDisplayPortOffset,
|
||||
float* aDisplayPortLength)
|
||||
/**
|
||||
* Attempts to enlarge the displayport along a single axis based on the
|
||||
* velocity. aOffset and aLength are in/out parameters; they are initially set
|
||||
* to the currently visible area and will be transformed to the area we should
|
||||
* be drawing to minimize checkerboarding.
|
||||
*/
|
||||
static void
|
||||
EnlargeDisplayPortAlongAxis(float* aOutOffset, float* aOutLength,
|
||||
double aEstimatedPaintDurationMillis, float aVelocity,
|
||||
float aStationarySizeMultiplier, float aSkateSizeMultiplier)
|
||||
{
|
||||
if (fabsf(aVelocity) > gMinSkateSpeed) {
|
||||
// Enlarge the area we paint.
|
||||
*aDisplayPortLength = aCompositionBounds * aSkateSizeMultiplier;
|
||||
// Position the area we paint such that all of the excess that extends past
|
||||
// the screen is on the side towards the velocity.
|
||||
*aDisplayPortOffset = aVelocity > 0 ? 0 : aCompositionBounds - *aDisplayPortLength;
|
||||
// Scale up the length using the appropriate multiplier and center the
|
||||
// displayport around the visible area.
|
||||
float multiplier = (fabsf(aVelocity) < gMinSkateSpeed
|
||||
? aStationarySizeMultiplier
|
||||
: aSkateSizeMultiplier);
|
||||
float newLength = (*aOutLength) * multiplier;
|
||||
*aOutOffset -= (newLength - (*aOutLength)) / 2;
|
||||
*aOutLength = newLength;
|
||||
|
||||
// Only compensate for acceleration when we actually have any. Otherwise
|
||||
// we'll overcompensate when a user is just panning around without flinging.
|
||||
if (aAcceleration > 1.01f) {
|
||||
// Compensate for acceleration and how long we expect a paint to take. We
|
||||
// try to predict where the viewport will be when painting has finished.
|
||||
*aDisplayPortOffset +=
|
||||
fabsf(aAcceleration) * aVelocity * aCompositionBounds * aEstimatedPaintDuration;
|
||||
// If our velocity is in the negative direction of the axis, we have to
|
||||
// compensate for the fact that our scroll offset is the top-left position
|
||||
// of the viewport. In this case, let's make it relative to the
|
||||
// bottom-right. That way, we'll always be growing the displayport upwards
|
||||
// and to the left when skating negatively.
|
||||
*aDisplayPortOffset -= aVelocity < 0 ? aCompositionBounds : 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// Project the displayport out based on the estimated time it will take to paint
|
||||
*aOutOffset += (aVelocity * aEstimatedPaintDurationMillis);
|
||||
}
|
||||
|
||||
/* static */
|
||||
const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const gfx::Point& aVelocity,
|
||||
const ScreenPoint& aVelocity,
|
||||
const gfx::Point& aAcceleration,
|
||||
double aEstimatedPaintDuration)
|
||||
{
|
||||
// If we don't get an estimated paint duration, we probably don't have any
|
||||
// data. In this case, we're dealing with either a stationary frame or a first
|
||||
// paint. In either of these cases, we can just assume it'll take 1 second to
|
||||
// paint. Getting this correct is not important anyways since it's only really
|
||||
// useful when accelerating, which can't be happening at this point.
|
||||
double estimatedPaintDuration =
|
||||
aEstimatedPaintDuration > EPSILON ? aEstimatedPaintDuration : 1.0;
|
||||
// convert to milliseconds
|
||||
double estimatedPaintDurationMillis = aEstimatedPaintDuration * 1000;
|
||||
|
||||
CSSIntRect compositionBounds = gfx::RoundedIn(aFrameMetrics.mCompositionBounds / aFrameMetrics.mZoom);
|
||||
CSSRect compositionBounds = aFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
CSSRect displayPort(scrollOffset, compositionBounds.Size());
|
||||
CSSPoint velocity = aVelocity / aFrameMetrics.mZoom;
|
||||
|
||||
// Enlarge the displayport along both axes depending on how fast we're moving
|
||||
// on that axis and how long it takes to paint. Apply some heuristics to try
|
||||
// to minimize checkerboarding.
|
||||
EnlargeDisplayPortAlongAxis(&(displayPort.x), &(displayPort.width),
|
||||
estimatedPaintDurationMillis, velocity.x,
|
||||
gXStationarySizeMultiplier, gXSkateSizeMultiplier);
|
||||
EnlargeDisplayPortAlongAxis(&(displayPort.y), &(displayPort.height),
|
||||
estimatedPaintDurationMillis, velocity.y,
|
||||
gYStationarySizeMultiplier, gYSkateSizeMultiplier);
|
||||
|
||||
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
||||
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
|
||||
|
||||
CSSRect displayPort = CSSRect(compositionBounds);
|
||||
displayPort.MoveTo(0, 0);
|
||||
displayPort.Scale(gXStationarySizeMultiplier, gYStationarySizeMultiplier);
|
||||
APZC_LOG_FM(aFrameMetrics,
|
||||
"Calculated displayport as (%f %f %f %f) from velocity (%f %f) acceleration (%f %f) paint time %f metrics",
|
||||
displayPort.x, displayPort.y, displayPort.width, displayPort.height,
|
||||
aVelocity.x, aVelocity.y, aAcceleration.x, aAcceleration.y,
|
||||
(float)estimatedPaintDurationMillis);
|
||||
|
||||
// If there's motion along an axis of movement, and it's above a threshold,
|
||||
// then we want to paint a larger area in the direction of that motion so that
|
||||
// it's less likely to checkerboard.
|
||||
bool enlargedX = EnlargeDisplayPortAlongAxis(
|
||||
gXSkateSizeMultiplier, estimatedPaintDuration,
|
||||
compositionBounds.width, aVelocity.x, aAcceleration.x,
|
||||
&displayPort.x, &displayPort.width);
|
||||
bool enlargedY = EnlargeDisplayPortAlongAxis(
|
||||
gYSkateSizeMultiplier, estimatedPaintDuration,
|
||||
compositionBounds.height, aVelocity.y, aAcceleration.y,
|
||||
&displayPort.y, &displayPort.height);
|
||||
|
||||
if (!enlargedX && !enlargedY) {
|
||||
// Position the x and y such that the screen falls in the middle of the displayport.
|
||||
displayPort.x = -(displayPort.width - compositionBounds.width) / 2;
|
||||
displayPort.y = -(displayPort.height - compositionBounds.height) / 2;
|
||||
} else if (!enlargedX) {
|
||||
displayPort.width = compositionBounds.width;
|
||||
} else if (!enlargedY) {
|
||||
displayPort.height = compositionBounds.height;
|
||||
}
|
||||
|
||||
// If we go over the bounds when trying to predict where we will be when this
|
||||
// paint finishes, move it back into the range of the CSS content rect.
|
||||
// FIXME/bug 780395: Generalize this. This code is pretty hacky as it will
|
||||
// probably not work at all for RTL content. This is not intended to be
|
||||
// incredibly accurate; it'll just prevent the entire displayport from being
|
||||
// outside the content rect (which causes bad things to happen).
|
||||
if (scrollOffset.x + compositionBounds.width > scrollableRect.width) {
|
||||
scrollOffset.x -= compositionBounds.width + scrollOffset.x - scrollableRect.width;
|
||||
} else if (scrollOffset.x < scrollableRect.x) {
|
||||
scrollOffset.x = scrollableRect.x;
|
||||
}
|
||||
if (scrollOffset.y + compositionBounds.height > scrollableRect.height) {
|
||||
scrollOffset.y -= compositionBounds.height + scrollOffset.y - scrollableRect.height;
|
||||
} else if (scrollOffset.y < scrollableRect.y) {
|
||||
scrollOffset.y = scrollableRect.y;
|
||||
}
|
||||
|
||||
return displayPort.ForceInside(scrollableRect - scrollOffset);
|
||||
return displayPort;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScheduleComposite() {
|
||||
|
@ -1598,7 +1564,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
|
|||
endZoomToMetrics.mScrollOffset = aRect.TopLeft();
|
||||
endZoomToMetrics.mDisplayPort =
|
||||
CalculatePendingDisplayPort(endZoomToMetrics,
|
||||
gfx::Point(0,0),
|
||||
ScreenPoint(0,0),
|
||||
gfx::Point(0,0),
|
||||
0);
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ public:
|
|||
*/
|
||||
static const CSSRect CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const gfx::Point& aVelocity,
|
||||
const ScreenPoint& aVelocity,
|
||||
const gfx::Point& aAcceleration,
|
||||
double aEstimatedPaintDuration);
|
||||
|
||||
|
@ -408,7 +408,7 @@ protected:
|
|||
/**
|
||||
* Gets a vector of the velocities of each axis.
|
||||
*/
|
||||
const gfx::Point GetVelocityVector();
|
||||
const ScreenPoint GetVelocityVector();
|
||||
|
||||
/**
|
||||
* Gets a vector of the acceleration factors of each axis.
|
||||
|
@ -439,22 +439,6 @@ protected:
|
|||
*/
|
||||
void TrackTouch(const MultiTouchInput& aEvent);
|
||||
|
||||
/**
|
||||
* Attempts to enlarge the displayport along a single axis. Returns whether or
|
||||
* not the displayport was enlarged. This will fail in circumstances where the
|
||||
* velocity along that axis is not high enough to need any changes. The
|
||||
* displayport metrics are expected to be passed into |aDisplayPortOffset| and
|
||||
* |aDisplayPortLength|. If enlarged, these will be updated with the new
|
||||
* metrics.
|
||||
*/
|
||||
static bool EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier,
|
||||
double aEstimatedPaintDuration,
|
||||
float aCompositionBounds,
|
||||
float aVelocity,
|
||||
float aAcceleration,
|
||||
float* aDisplayPortOffset,
|
||||
float* aDisplayPortLength);
|
||||
|
||||
/**
|
||||
* Utility function to send updated FrameMetrics to Gecko so that it can paint
|
||||
* the displayport area. Calls into GeckoContentController to do the actual
|
||||
|
|
|
@ -29,111 +29,98 @@ extern PRLogModuleInfo *GetImgLog();
|
|||
|
||||
class LogScope {
|
||||
public:
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn) :
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get()));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
}
|
||||
|
||||
/* const char * constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
|
||||
const nsDependentCString ¶mName, const char *paramValue) :
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const char *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* void ptr constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
|
||||
const nsDependentCString ¶mName, const void *paramValue) :
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const void *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=%p) {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* int32_t constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
|
||||
const nsDependentCString ¶mName, int32_t paramValue) :
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, int32_t paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* uint32_t constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
|
||||
const nsDependentCString ¶mName, uint32_t paramValue) :
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, uint32_t paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
|
||||
~LogScope() {
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {EXIT}\n",
|
||||
GIVE_ME_MS_NOW(),
|
||||
mFrom, mFunc.get()));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
}
|
||||
|
||||
private:
|
||||
PRLogModuleInfo *mLog;
|
||||
void *mFrom;
|
||||
nsAutoCString mFunc;
|
||||
const char *mFunc;
|
||||
};
|
||||
|
||||
|
||||
class LogFunc {
|
||||
public:
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn)
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn.get()));
|
||||
GIVE_ME_MS_NOW(), from, fn));
|
||||
}
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
|
||||
const nsDependentCString ¶mName, const char *paramValue)
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const char *paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\")\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn.get(),
|
||||
paramName.get(), paramValue));
|
||||
GIVE_ME_MS_NOW(), from, fn,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
|
||||
const nsDependentCString ¶mName, const void *paramValue)
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const void *paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%p\")\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn.get(),
|
||||
paramName.get(), paramValue));
|
||||
GIVE_ME_MS_NOW(), from, fn,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
|
||||
const nsDependentCString ¶mName, uint32_t paramValue)
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, uint32_t paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\")\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn.get(),
|
||||
paramName.get(), paramValue));
|
||||
fn,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -141,13 +128,11 @@ public:
|
|||
|
||||
class LogMessage {
|
||||
public:
|
||||
LogMessage(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
|
||||
const nsDependentCString &msg)
|
||||
LogMessage(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *msg)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s -- %s\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn.get(),
|
||||
msg.get()));
|
||||
GIVE_ME_MS_NOW(), from, fn, msg));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -156,45 +141,22 @@ public:
|
|||
#define LOG_SCOPE_APPEND_LINE_NUMBER(id) LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
|
||||
|
||||
#define LOG_SCOPE(l, s) \
|
||||
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \
|
||||
static_cast<void *>(this), \
|
||||
NS_LITERAL_CSTRING(s))
|
||||
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s)
|
||||
|
||||
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
|
||||
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \
|
||||
static_cast<void *>(this), \
|
||||
NS_LITERAL_CSTRING(s), \
|
||||
NS_LITERAL_CSTRING(pn), pv)
|
||||
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s, pn, pv)
|
||||
|
||||
#define LOG_FUNC(l, s) \
|
||||
LogFunc(l, \
|
||||
static_cast<void *>(this), \
|
||||
NS_LITERAL_CSTRING(s))
|
||||
#define LOG_FUNC(l, s) LogFunc(l, this, s)
|
||||
|
||||
#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) \
|
||||
LogFunc(l, \
|
||||
static_cast<void *>(this), \
|
||||
NS_LITERAL_CSTRING(s), \
|
||||
NS_LITERAL_CSTRING(pn), pv)
|
||||
#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, this, s, pn, pv)
|
||||
|
||||
#define LOG_STATIC_FUNC(l, s) \
|
||||
LogFunc(l, \
|
||||
nullptr, \
|
||||
NS_LITERAL_CSTRING(s))
|
||||
#define LOG_STATIC_FUNC(l, s) LogFunc(l, nullptr, s)
|
||||
|
||||
#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) \
|
||||
LogFunc(l, \
|
||||
nullptr, \
|
||||
NS_LITERAL_CSTRING(s), \
|
||||
NS_LITERAL_CSTRING(pn), pv)
|
||||
#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, nullptr, s, pn, pv)
|
||||
|
||||
|
||||
|
||||
#define LOG_MSG(l, s, m) \
|
||||
LogMessage(l, \
|
||||
static_cast<void *>(this), \
|
||||
NS_LITERAL_CSTRING(s), \
|
||||
NS_LITERAL_CSTRING(m))
|
||||
#define LOG_MSG(l, s, m) LogMessage(l, this, s, m)
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -314,6 +314,12 @@ struct ParamTraits<nsCString> : ParamTraits<nsACString>
|
|||
typedef nsCString paramType;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString>
|
||||
{
|
||||
typedef nsLiteralCString paramType;
|
||||
};
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
|
||||
template<>
|
||||
|
@ -330,6 +336,12 @@ struct ParamTraits<nsString> : ParamTraits<nsAString>
|
|||
typedef nsString paramType;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<nsLiteralString> : ParamTraits<nsAString>
|
||||
{
|
||||
typedef nsLiteralString paramType;
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
struct ParamTraits<FallibleTArray<E> >
|
||||
{
|
||||
|
|
|
@ -335,6 +335,14 @@ const Class SIMDObject::class_ = {
|
|||
JSObject *
|
||||
SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
// SIMD relies on having the TypedObject module initialized.
|
||||
// In particular, the self-hosted code for array() wants
|
||||
// to be able to call GetTypedObjectModule(). It is NOT necessary
|
||||
// to install the TypedObjectModule global, but at the moment
|
||||
// those two things are not separable.
|
||||
if (!global->getOrCreateTypedObjectModule(cx))
|
||||
return nullptr;
|
||||
|
||||
// Create SIMD Object.
|
||||
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
|
||||
if(!objProto)
|
||||
|
|
|
@ -947,6 +947,8 @@ SizedTypeRepresentation::initInstance(const JSRuntime *rt,
|
|||
uint8_t *mem,
|
||||
size_t length)
|
||||
{
|
||||
JS_ASSERT(length >= 1);
|
||||
|
||||
MemoryInitVisitor visitor(rt);
|
||||
|
||||
// Initialize the 0th instance
|
||||
|
|
|
@ -231,7 +231,8 @@ class SizedTypeRepresentation : public TypeRepresentation {
|
|||
size_t size() const { return size_; }
|
||||
size_t alignment() const { return alignment_; }
|
||||
|
||||
// Initializes memory that contains `count` instances of this type
|
||||
// Initializes memory that contains `count` instances of this type.
|
||||
// `count` must be at least 1.
|
||||
void initInstance(const JSRuntime *rt, uint8_t *mem, size_t count);
|
||||
|
||||
// Traces memory that contains `count` instances of this type.
|
||||
|
|
|
@ -2339,7 +2339,8 @@ TypedObject::createZeroed(JSContext *cx,
|
|||
if (!memory)
|
||||
return nullptr;
|
||||
|
||||
elementTypeRepr->initInstance(cx->runtime(), memory, length);
|
||||
if (length)
|
||||
elementTypeRepr->initInstance(cx->runtime(), memory, length);
|
||||
obj->attach(memory);
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
if (!this.hasOwnProperty("TypedObject"))
|
||||
quit();
|
||||
|
||||
var float32x4 = SIMD.float32x4;
|
||||
float32x4.array(1);
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
if (!this.hasOwnProperty("TypedObject"))
|
||||
quit();
|
||||
|
||||
// bug 953111
|
||||
|
||||
var A = TypedObject.uint8.array();
|
||||
var a = new A(0);
|
||||
a.forEach(function(val, i) {});
|
||||
|
||||
// bug 951356 (dup, but a dup that is more likely to crash)
|
||||
|
||||
var AA = TypedObject.uint8.array(2147483647).array();
|
||||
var aa = new AA(0);
|
|
@ -6686,7 +6686,7 @@ IonBuilder::getElemTryScalarElemOfTypedObject(bool *emitted,
|
|||
TypeRepresentationSet elemTypeReprs,
|
||||
size_t elemSize)
|
||||
{
|
||||
JS_ASSERT(objTypeReprs.kind() == TypeRepresentation::SizedArray);
|
||||
JS_ASSERT(objTypeReprs.allOfArrayKind());
|
||||
|
||||
// Must always be loading the same scalar type
|
||||
if (!elemTypeReprs.singleton())
|
||||
|
|
|
@ -703,19 +703,21 @@ CodeGeneratorARM::modICommon(MMod *mir, Register lhs, Register rhs, Register out
|
|||
// the flags necessary for LT to trigger, we don't test X, and take the
|
||||
// bailout because the EQ flag is set.
|
||||
// if (Y > 0), we don't set EQ, and we don't trigger LT, so we don't take the bailout.
|
||||
masm.ma_cmp(rhs, Imm32(0));
|
||||
masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
|
||||
if (mir->isTruncated()) {
|
||||
// NaN|0 == 0 and (0 % -X)|0 == 0
|
||||
Label skip;
|
||||
masm.ma_b(&skip, Assembler::NotEqual);
|
||||
masm.ma_mov(Imm32(0), output);
|
||||
masm.ma_b(&done);
|
||||
masm.bind(&skip);
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Equal, snapshot))
|
||||
return false;
|
||||
if (mir->canBeDivideByZero() || mir->canBeNegativeDividend()) {
|
||||
masm.ma_cmp(rhs, Imm32(0));
|
||||
masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
|
||||
if (mir->isTruncated()) {
|
||||
// NaN|0 == 0 and (0 % -X)|0 == 0
|
||||
Label skip;
|
||||
masm.ma_b(&skip, Assembler::NotEqual);
|
||||
masm.ma_mov(Imm32(0), output);
|
||||
masm.ma_b(&done);
|
||||
masm.bind(&skip);
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Equal, snapshot))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -740,16 +742,18 @@ CodeGeneratorARM::visitModI(LModI *ins)
|
|||
masm.ma_smod(lhs, rhs, output);
|
||||
|
||||
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
|
||||
if (mir->isTruncated()) {
|
||||
// -0.0|0 == 0
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
// See if X < 0
|
||||
masm.ma_cmp(output, Imm32(0));
|
||||
masm.ma_b(&done, Assembler::NotEqual);
|
||||
masm.ma_cmp(callTemp, Imm32(0));
|
||||
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
|
||||
return false;
|
||||
if (mir->canBeNegativeDividend()) {
|
||||
if (mir->isTruncated()) {
|
||||
// -0.0|0 == 0
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
// See if X < 0
|
||||
masm.ma_cmp(output, Imm32(0));
|
||||
masm.ma_b(&done, Assembler::NotEqual);
|
||||
masm.ma_cmp(callTemp, Imm32(0));
|
||||
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
|
@ -802,16 +806,18 @@ CodeGeneratorARM::visitSoftModI(LSoftModI *ins)
|
|||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
|
||||
|
||||
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
|
||||
if (mir->isTruncated()) {
|
||||
// -0.0|0 == 0
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
// See if X < 0
|
||||
masm.ma_cmp(r1, Imm32(0));
|
||||
masm.ma_b(&done, Assembler::NotEqual);
|
||||
masm.ma_cmp(callTemp, Imm32(0));
|
||||
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
|
||||
return false;
|
||||
if (mir->canBeNegativeDividend()) {
|
||||
if (mir->isTruncated()) {
|
||||
// -0.0|0 == 0
|
||||
} else {
|
||||
JS_ASSERT(mir->fallible());
|
||||
// See if X < 0
|
||||
masm.ma_cmp(r1, Imm32(0));
|
||||
masm.ma_b(&done, Assembler::NotEqual);
|
||||
masm.ma_cmp(callTemp, Imm32(0));
|
||||
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
masm.bind(&done);
|
||||
return true;
|
||||
|
@ -830,12 +836,14 @@ CodeGeneratorARM::visitModPowTwoI(LModPowTwoI *ins)
|
|||
masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed);
|
||||
masm.ma_and(Imm32((1<<ins->shift())-1), out);
|
||||
masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed);
|
||||
if (!mir->isTruncated()) {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
// -0|0 == 0
|
||||
if (mir->canBeNegativeDividend()) {
|
||||
if (!mir->isTruncated()) {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
// -0|0 == 0
|
||||
}
|
||||
}
|
||||
masm.bind(&fin);
|
||||
return true;
|
||||
|
@ -849,12 +857,14 @@ CodeGeneratorARM::visitModMaskI(LModMaskI *ins)
|
|||
Register tmp = ToRegister(ins->getTemp(0));
|
||||
MMod *mir = ins->mir();
|
||||
masm.ma_mod_mask(src, dest, tmp, ins->shift());
|
||||
if (!mir->isTruncated()) {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
// -0|0 == 0
|
||||
if (mir->canBeNegativeDividend()) {
|
||||
if (!mir->isTruncated()) {
|
||||
JS_ASSERT(mir->fallible());
|
||||
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
// -0|0 == 0
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3209,7 +3209,7 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx)
|
|||
}
|
||||
|
||||
if (!finished) {
|
||||
if (!obj->rollbackProperties(cx, numProperties))
|
||||
if (!JSObject::rollbackProperties(cx, obj, numProperties))
|
||||
cx->compartment()->types.setPendingNukeTypes(cx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -416,7 +416,8 @@ class JSObject : public js::ObjectImpl
|
|||
elements[i].js::HeapSlot::~HeapSlot();
|
||||
}
|
||||
|
||||
bool rollbackProperties(js::ExclusiveContext *cx, uint32_t slotSpan);
|
||||
static bool rollbackProperties(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
uint32_t slotSpan);
|
||||
|
||||
void nativeSetSlot(uint32_t slot, const js::Value &value) {
|
||||
JS_ASSERT(isNative());
|
||||
|
|
|
@ -1156,26 +1156,26 @@ JSObject::clear(JSContext *cx, HandleObject obj)
|
|||
obj->checkShapeConsistency();
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::rollbackProperties(ExclusiveContext *cx, uint32_t slotSpan)
|
||||
/* static */ bool
|
||||
JSObject::rollbackProperties(ExclusiveContext *cx, HandleObject obj, uint32_t slotSpan)
|
||||
{
|
||||
/*
|
||||
* Remove properties from this object until it has a matching slot span.
|
||||
* The object cannot have escaped in a way which would prevent safe
|
||||
* removal of the last properties.
|
||||
*/
|
||||
JS_ASSERT(!inDictionaryMode() && slotSpan <= this->slotSpan());
|
||||
JS_ASSERT(!obj->inDictionaryMode() && slotSpan <= obj->slotSpan());
|
||||
while (true) {
|
||||
if (lastProperty()->isEmptyShape()) {
|
||||
if (obj->lastProperty()->isEmptyShape()) {
|
||||
JS_ASSERT(slotSpan == 0);
|
||||
break;
|
||||
} else {
|
||||
uint32_t slot = lastProperty()->slot();
|
||||
uint32_t slot = obj->lastProperty()->slot();
|
||||
if (slot < slotSpan)
|
||||
break;
|
||||
JS_ASSERT(getSlot(slot).isUndefined());
|
||||
JS_ASSERT(obj->getSlot(slot).isUndefined());
|
||||
}
|
||||
if (!removeProperty(cx, lastProperty()->propid()))
|
||||
if (!obj->removeProperty(cx, obj->lastProperty()->propid()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,15 @@ XPCStringConvert::ClearZoneCache(JS::Zone *zone)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
XPCStringConvert::FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars)
|
||||
{
|
||||
}
|
||||
|
||||
const JSStringFinalizer XPCStringConvert::sLiteralFinalizer =
|
||||
{ XPCStringConvert::FinalizeLiteral };
|
||||
|
||||
// static
|
||||
void
|
||||
XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
|
||||
|
@ -74,6 +83,16 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (readable.IsLiteral()) {
|
||||
JSString *str = JS_NewExternalString(cx,
|
||||
static_cast<const jschar*>(readable.BeginReading()),
|
||||
length, &sLiteralFinalizer);
|
||||
if (!str)
|
||||
return false;
|
||||
vp.setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsStringBuffer *buf = nsStringBuffer::FromString(readable);
|
||||
if (buf) {
|
||||
bool shared;
|
||||
|
|
|
@ -238,7 +238,9 @@ public:
|
|||
static void ClearZoneCache(JS::Zone *zone);
|
||||
|
||||
private:
|
||||
static const JSStringFinalizer sDOMStringFinalizer;
|
||||
static const JSStringFinalizer sLiteralFinalizer, sDOMStringFinalizer;
|
||||
|
||||
static void FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars);
|
||||
|
||||
static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);
|
||||
|
||||
|
|
|
@ -376,7 +376,9 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
|
|||
if (kidContent) {
|
||||
NS_ASSERTION(kidContent->IsNodeOfType(nsINode::eTEXT),
|
||||
"should contain only text nodes");
|
||||
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(mStyleContext);
|
||||
nsStyleContext* parentSC = prevInFlow ? mStyleContext->GetParent() :
|
||||
mStyleContext;
|
||||
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(parentSC);
|
||||
kid->SetStyleContext(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1359,8 +1359,9 @@ nsFlexContainerFrame::SanityCheckAnonymousFlexItems() const
|
|||
"but it isn't");
|
||||
if (child->StyleContext()->GetPseudo() ==
|
||||
nsCSSAnonBoxes::anonymousFlexItem) {
|
||||
MOZ_ASSERT(!prevChildWasAnonFlexItem,
|
||||
"two anon flex items in a row (shouldn't happen)");
|
||||
MOZ_ASSERT(!prevChildWasAnonFlexItem || mChildrenHaveBeenReordered,
|
||||
"two anon flex items in a row (shouldn't happen, unless our "
|
||||
"children have been reordered with the 'order' property)");
|
||||
|
||||
nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild();
|
||||
MOZ_ASSERT(firstWrappedChild,
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<style type="text/css">
|
||||
#descdiv{
|
||||
overflow: hidden;
|
||||
height: 60px;
|
||||
border: 1px solid red;
|
||||
}
|
||||
#descdiv p{
|
||||
height:30px;
|
||||
margin:0;
|
||||
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
|
||||
This causes the text to be drawn even when it's outside of the clip*/
|
||||
text-shadow: #fff 1px -1px 2px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="descdiv">
|
||||
<p class="um_desc"> </p>
|
||||
<p class="um_desc"> </p>
|
||||
<p class="um_desc"> </p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<style type="text/css">
|
||||
#descdiv{
|
||||
overflow: hidden;
|
||||
height: 60px;
|
||||
border: 1px solid red;
|
||||
}
|
||||
#descdiv p{
|
||||
height:30px;
|
||||
margin:0;
|
||||
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
|
||||
This causes the text to be drawn even when it's outside of the clip*/
|
||||
text-shadow: #fff 1px -1px 2px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="descdiv">
|
||||
<p class="um_desc"> </p>
|
||||
<p class="um_desc"> </p>
|
||||
<p class="um_desc">sed diam nonummy nibh</p>
|
||||
</div>
|
||||
|
|
@ -1791,5 +1791,6 @@ fuzzy-if(OSX==10.6,2,30) == 933264-1.html 933264-1-ref.html
|
|||
== 941940-1.html 941940-1-ref.html
|
||||
== 942017.html 942017-ref.html
|
||||
== 942672-1.html 942672-1-ref.html
|
||||
== 953334-win32-clipping.html 953334-win32-clipping-ref.html
|
||||
== 956513-1.svg 956513-1-ref.svg
|
||||
== 944291-1.html 944291-1-ref.html
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
a ab bx x
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: Testing that we gracefully handle cases where two anonymous flex items become adjacent due to "order" reordering</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#flex-items">
|
||||
<link rel="match" href="flexbox-anonymous-items-1-ref.html">
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
.flexContainer {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer">
|
||||
a a
|
||||
<div style="order: 1">x x</div>
|
||||
b b
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,3 +1,6 @@
|
|||
# Tests for handling anonymous flex items
|
||||
== flexbox-anonymous-items-1.html flexbox-anonymous-items-1-ref.html
|
||||
|
||||
# Tests for alignment of flex lines (align-content property)
|
||||
== flexbox-align-content-horiz-1a.xhtml flexbox-align-content-horiz-1-ref.xhtml
|
||||
== flexbox-align-content-horiz-1b.xhtml flexbox-align-content-horiz-1-ref.xhtml
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#include "android/log.h"
|
||||
|
||||
#define MAX_DECODER_NAME_LEN 256
|
||||
#define AVC_MIME_TYPE "video/avc"
|
||||
|
||||
#if !defined(MOZ_ANDROID_FROYO)
|
||||
#define DEFAULT_STAGEFRIGHT_FLAGS OMXCodec::kClientNeedsFramebuffer
|
||||
#else
|
||||
|
@ -239,7 +242,13 @@ static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost)
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
enum ColorFormatSupport {
|
||||
ColorFormatNotSupported = 0,
|
||||
ColorFormatSupportOK,
|
||||
ColorFormatSupportPreferred,
|
||||
};
|
||||
|
||||
static ColorFormatSupport
|
||||
IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
|
||||
{
|
||||
switch (aColorFormat) {
|
||||
|
@ -250,15 +259,19 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
|
|||
case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
|
||||
case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
|
||||
LOG("Colour format %#x supported natively.", aColorFormat);
|
||||
return true;
|
||||
// Prefer natively supported colour formats over formats that need another
|
||||
// slow software conversion.
|
||||
return ColorFormatSupportPreferred;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// These formats are okay if we can't find a better one; Android provides a
|
||||
// software conversion to a sane colour format.
|
||||
#if !defined(MOZ_ANDROID_HC)
|
||||
if (ColorConverter(aColorFormat, OMX_COLOR_Format16bitRGB565).isValid()) {
|
||||
LOG("Colour format %#x supported by Android ColorConverter.", aColorFormat);
|
||||
return true;
|
||||
return ColorFormatSupportOK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -268,12 +281,64 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
|
|||
if (yuvConverter.isLoaded() &&
|
||||
yuvConverter.getDecoderOutputFormat() == aColorFormat) {
|
||||
LOG("Colour format %#x supported by Android I420ColorConverter.", aColorFormat);
|
||||
return true;
|
||||
return ColorFormatSupportOK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ColorFormatNotSupported;
|
||||
}
|
||||
|
||||
#if defined(MOZ_ANDROID_KK)
|
||||
/**
|
||||
* Look for a decoder that supports a colour format that we support.
|
||||
*/
|
||||
static bool
|
||||
FindPreferredDecoderAndColorFormat(const sp<IOMX>& aOmx,
|
||||
char *aDecoderName,
|
||||
size_t aDecoderLen,
|
||||
OMX_COLOR_FORMATTYPE *aColorFormat)
|
||||
{
|
||||
Vector<CodecCapabilities> codecs;
|
||||
|
||||
// Get all AVC decoder/colour format pairs that this device supports.
|
||||
QueryCodecs(aOmx, AVC_MIME_TYPE, true /* queryDecoders */, &codecs);
|
||||
|
||||
// We assume that faster (hardware accelerated) decoders come first in the
|
||||
// list, so we choose the first decoder with a colour format we can use.
|
||||
for (uint32_t i = 0; i < codecs.size(); i++) {
|
||||
const CodecCapabilities &caps = codecs[i];
|
||||
const Vector<OMX_U32> &colors = caps.mColorFormats;
|
||||
|
||||
bool found = false;
|
||||
for (uint32_t j = 0; j < colors.size(); j++) {
|
||||
OMX_COLOR_FORMATTYPE color = (OMX_COLOR_FORMATTYPE)colors[j];
|
||||
|
||||
LOG("Decoder %s can output colour format %#x.\n",
|
||||
caps.mComponentName.string(), color);
|
||||
|
||||
ColorFormatSupport supported = IsColorFormatSupported(color);
|
||||
|
||||
if (supported) {
|
||||
strncpy(aDecoderName, caps.mComponentName.string(), aDecoderLen);
|
||||
*aColorFormat = (OMX_COLOR_FORMATTYPE)color;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (supported == ColorFormatSupportPreferred) {
|
||||
// The colour format is natively supported -- that's as good as we're
|
||||
// going to get.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
|
||||
const sp<IOMX>& aOmx,
|
||||
|
@ -281,10 +346,29 @@ static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
|
|||
{
|
||||
uint32_t flags = GetVideoCreationFlags(aPluginHost);
|
||||
|
||||
char decoderName[MAX_DECODER_NAME_LEN] = "";
|
||||
sp<MetaData> videoFormat = aVideoTrack->getFormat();
|
||||
|
||||
#if defined(MOZ_ANDROID_KK)
|
||||
OMX_COLOR_FORMATTYPE colorFormat = (OMX_COLOR_FORMATTYPE)0;
|
||||
if (FindPreferredDecoderAndColorFormat(aOmx,
|
||||
decoderName, sizeof(decoderName),
|
||||
&colorFormat)) {
|
||||
// We found a colour format that we can handle. Tell OMXCodec to use it in
|
||||
// case it isn't the default.
|
||||
videoFormat->setInt32(kKeyColorFormat, colorFormat);
|
||||
|
||||
LOG("Found compatible decoder %s with colour format %#x.\n",
|
||||
decoderName, colorFormat);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags == DEFAULT_STAGEFRIGHT_FLAGS) {
|
||||
// Let Stagefright choose hardware or software decoder.
|
||||
sp<MediaSource> videoSource = OMXCodec::Create(aOmx, aVideoTrack->getFormat(),
|
||||
false, aVideoTrack, nullptr, flags);
|
||||
sp<MediaSource> videoSource = OMXCodec::Create(aOmx, videoFormat,
|
||||
false, aVideoTrack,
|
||||
decoderName[0] ? decoderName : nullptr,
|
||||
flags);
|
||||
if (videoSource == nullptr)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <utils/VectorImpl.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
|
@ -43,11 +44,11 @@ class Vector : private VectorImpl
|
|||
{
|
||||
public:
|
||||
typedef TYPE value_type;
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* Constructors and destructors
|
||||
*/
|
||||
|
||||
|
||||
Vector();
|
||||
Vector(const Vector<TYPE>& rhs);
|
||||
explicit Vector(const SortedVector<TYPE>& rhs);
|
||||
|
@ -55,7 +56,7 @@ public:
|
|||
|
||||
/*! copy operator */
|
||||
const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
|
||||
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
|
||||
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
|
||||
|
||||
const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
|
||||
Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
|
||||
|
@ -66,29 +67,35 @@ public:
|
|||
|
||||
inline void clear() { VectorImpl::clear(); }
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* vector stats
|
||||
*/
|
||||
|
||||
//! returns number of items in the vector
|
||||
inline size_t size() const { return VectorImpl::size(); }
|
||||
//! returns wether or not the vector is empty
|
||||
//! returns whether or not the vector is empty
|
||||
inline bool isEmpty() const { return VectorImpl::isEmpty(); }
|
||||
//! returns how many items can be stored without reallocating the backing store
|
||||
inline size_t capacity() const { return VectorImpl::capacity(); }
|
||||
//! setst the capacity. capacity can never be reduced less than size()
|
||||
//! sets the capacity. capacity can never be reduced less than size()
|
||||
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* set the size of the vector. items are appended with the default
|
||||
* constructor, or removed from the end as needed.
|
||||
*/
|
||||
inline ssize_t resize(size_t size) { return VectorImpl::resize(size); }
|
||||
|
||||
/*!
|
||||
* C-style array access
|
||||
*/
|
||||
|
||||
//! read-only C-style access
|
||||
|
||||
//! read-only C-style access
|
||||
inline const TYPE* array() const;
|
||||
//! read-write C-style access
|
||||
TYPE* editArray();
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* accessors
|
||||
*/
|
||||
|
||||
|
@ -98,22 +105,20 @@ public:
|
|||
inline const TYPE& itemAt(size_t index) const;
|
||||
//! stack-usage of the vector. returns the top of the stack (last element)
|
||||
const TYPE& top() const;
|
||||
//! same as operator [], but allows to access the vector backward (from the end) with a negative index
|
||||
const TYPE& mirrorItemAt(ssize_t index) const;
|
||||
|
||||
/*!
|
||||
* modifing the array
|
||||
* modifying the array
|
||||
*/
|
||||
|
||||
//! copy-on write support, grants write access to an item
|
||||
TYPE& editItemAt(size_t index);
|
||||
//! grants right acces to the top of the stack (last element)
|
||||
//! grants right access to the top of the stack (last element)
|
||||
TYPE& editTop();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* append/insert another vector
|
||||
*/
|
||||
|
||||
|
||||
//! insert another vector at a given index
|
||||
ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index);
|
||||
|
||||
|
@ -127,10 +132,10 @@ public:
|
|||
//! append an array at the end of this vector
|
||||
ssize_t appendArray(const TYPE* array, size_t length);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* add/insert/replace items
|
||||
*/
|
||||
|
||||
|
||||
//! insert one or several items initialized with their default constructor
|
||||
inline ssize_t insertAt(size_t index, size_t numItems = 1);
|
||||
//! insert one or several items initialized from a prototype item
|
||||
|
@ -144,7 +149,7 @@ public:
|
|||
//! same as push() but returns the index the item was added at (or an error)
|
||||
inline ssize_t add();
|
||||
//! same as push() but returns the index the item was added at (or an error)
|
||||
ssize_t add(const TYPE& item);
|
||||
ssize_t add(const TYPE& item);
|
||||
//! replace an item with a new one initialized with its default constructor
|
||||
inline ssize_t replaceAt(size_t index);
|
||||
//! replace an item with a new one
|
||||
|
@ -162,10 +167,10 @@ public:
|
|||
/*!
|
||||
* sort (stable) the array
|
||||
*/
|
||||
|
||||
|
||||
typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
|
||||
typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
|
||||
|
||||
|
||||
inline status_t sort(compar_t cmp);
|
||||
inline status_t sort(compar_r_t cmp, void* state);
|
||||
|
||||
|
@ -186,10 +191,11 @@ public:
|
|||
inline const_iterator end() const { return array() + size(); }
|
||||
inline void reserve(size_t n) { setCapacity(n); }
|
||||
inline bool empty() const{ return isEmpty(); }
|
||||
inline void push_back(const TYPE& item) { insertAt(item, size()); }
|
||||
inline void push_front(const TYPE& item) { insertAt(item, 0); }
|
||||
inline void push_back(const TYPE& item) { insertAt(item, size(), 1); }
|
||||
inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
|
||||
inline iterator erase(iterator pos) {
|
||||
return begin() + removeItemsAt(pos-array());
|
||||
ssize_t index = removeItemsAt(pos-array());
|
||||
return begin() + index;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -201,6 +207,9 @@ protected:
|
|||
virtual void do_move_backward(void* dest, const void* from, size_t num) const;
|
||||
};
|
||||
|
||||
// Vector<T> can be trivially moved using memcpy() because moving does not
|
||||
// require any change to the underlying SharedBuffer contents or reference count.
|
||||
template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts from here...
|
||||
|
@ -234,7 +243,7 @@ Vector<TYPE>::~Vector() {
|
|||
template<class TYPE> inline
|
||||
Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
|
||||
VectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
|
@ -252,7 +261,7 @@ Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
|
|||
template<class TYPE> inline
|
||||
const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
|
||||
VectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
|
@ -268,8 +277,9 @@ TYPE* Vector<TYPE>::editArray() {
|
|||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::operator[](size_t index) const {
|
||||
LOG_FATAL_IF( index>=size(),
|
||||
"itemAt: index %d is past size %d", (int)index, (int)size() );
|
||||
LOG_FATAL_IF(index>=size(),
|
||||
"%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
|
||||
int(index), int(size()));
|
||||
return *(array() + index);
|
||||
}
|
||||
|
||||
|
@ -278,14 +288,6 @@ const TYPE& Vector<TYPE>::itemAt(size_t index) const {
|
|||
return operator[](index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
|
||||
LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
|
||||
"mirrorItemAt: index %d is past size %d",
|
||||
(int)index, (int)size() );
|
||||
return *(array() + ((index<0) ? (size()-index) : index));
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::top() const {
|
||||
return *(array() + size() - 1);
|
||||
|
@ -419,3 +421,4 @@ void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) co
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_VECTOR_H
|
||||
|
||||
|
|
|
@ -53,24 +53,25 @@ public:
|
|||
/*! must be called from subclasses destructor */
|
||||
void finish_vector();
|
||||
|
||||
VectorImpl& operator = (const VectorImpl& rhs);
|
||||
|
||||
VectorImpl& operator = (const VectorImpl& rhs);
|
||||
|
||||
/*! C-style array access */
|
||||
inline const void* arrayImpl() const { return mStorage; }
|
||||
void* editArrayImpl();
|
||||
|
||||
|
||||
/*! vector stats */
|
||||
inline size_t size() const { return mCount; }
|
||||
inline bool isEmpty() const { return mCount == 0; }
|
||||
size_t capacity() const;
|
||||
ssize_t setCapacity(size_t size);
|
||||
ssize_t resize(size_t size);
|
||||
|
||||
/*! append/insert another vector or array */
|
||||
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
|
||||
ssize_t appendVector(const VectorImpl& vector);
|
||||
ssize_t insertArrayAt(const void* array, size_t index, size_t length);
|
||||
ssize_t appendArray(const void* array, size_t length);
|
||||
|
||||
|
||||
/*! add/insert/replace items */
|
||||
ssize_t insertAt(size_t where, size_t numItems = 1);
|
||||
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
|
||||
|
@ -105,16 +106,6 @@ protected:
|
|||
virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
|
||||
virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
|
||||
|
||||
// take care of FBC...
|
||||
virtual void reservedVectorImpl1();
|
||||
virtual void reservedVectorImpl2();
|
||||
virtual void reservedVectorImpl3();
|
||||
virtual void reservedVectorImpl4();
|
||||
virtual void reservedVectorImpl5();
|
||||
virtual void reservedVectorImpl6();
|
||||
virtual void reservedVectorImpl7();
|
||||
virtual void reservedVectorImpl8();
|
||||
|
||||
private:
|
||||
void* _grow(size_t where, size_t amount);
|
||||
void _shrink(size_t where, size_t amount);
|
||||
|
@ -143,8 +134,8 @@ public:
|
|||
SortedVectorImpl(size_t itemSize, uint32_t flags);
|
||||
SortedVectorImpl(const VectorImpl& rhs);
|
||||
virtual ~SortedVectorImpl();
|
||||
|
||||
SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
|
||||
|
||||
SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
|
||||
|
||||
//! finds the index of an item
|
||||
ssize_t indexOf(const void* item) const;
|
||||
|
@ -158,23 +149,13 @@ public:
|
|||
//! merges a vector into this one
|
||||
ssize_t merge(const VectorImpl& vector);
|
||||
ssize_t merge(const SortedVectorImpl& vector);
|
||||
|
||||
|
||||
//! removes an item
|
||||
ssize_t remove(const void* item);
|
||||
|
||||
|
||||
protected:
|
||||
virtual int do_compare(const void* lhs, const void* rhs) const = 0;
|
||||
|
||||
// take care of FBC...
|
||||
virtual void reservedSortedVectorImpl1();
|
||||
virtual void reservedSortedVectorImpl2();
|
||||
virtual void reservedSortedVectorImpl3();
|
||||
virtual void reservedSortedVectorImpl4();
|
||||
virtual void reservedSortedVectorImpl5();
|
||||
virtual void reservedSortedVectorImpl6();
|
||||
virtual void reservedSortedVectorImpl7();
|
||||
virtual void reservedSortedVectorImpl8();
|
||||
|
||||
private:
|
||||
ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
|
||||
|
||||
|
@ -200,3 +181,4 @@ private:
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_VECTOR_IMPL_H
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Copyright 2012 Mozilla Foundation and Mozilla contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Don't use STL wrappers; this isn't Gecko code
|
||||
STL_FLAGS =
|
||||
|
||||
# must link statically with the CRT; this isn't Gecko code
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
-L$(DEPTH)/media/omx-plugin/lib/ics/libutils \
|
||||
-lutils \
|
||||
-L$(DEPTH)/media/omx-plugin/lib/ics/libstagefright \
|
||||
-lstagefright \
|
||||
-L$(DEPTH)/media/omx-plugin/lib/ics/libvideoeditorplayer \
|
||||
-lvideoeditorplayer \
|
||||
$(NULL)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
#define MOZ_STAGEFRIGHT_OFF_T off64_t
|
||||
#define MOZ_ANDROID_KK
|
||||
#include "../OmxPlugin.cpp"
|
|
@ -0,0 +1,20 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SOURCES += [
|
||||
'OmxPluginKitKat.cpp',
|
||||
]
|
||||
|
||||
LIBRARY_NAME = 'omxpluginkk'
|
||||
|
||||
FORCE_SHARED_LIB = True
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../../../content/media/plugins',
|
||||
'../include/ics',
|
||||
'../include/ics/media/stagefright/openmax',
|
||||
]
|
||||
|
|
@ -61,6 +61,12 @@ MetaData::findInt32(uint32_t key, int32_t *value)
|
|||
return false;
|
||||
}
|
||||
|
||||
MOZ_EXPORT bool
|
||||
MetaData::setInt32(uint32_t, int32_t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_EXPORT bool
|
||||
MetaData::findInt64(uint32_t key, int64_t *value)
|
||||
{
|
||||
|
@ -176,4 +182,12 @@ ColorConverter::convert(const void *srcBits,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MOZ_EXPORT status_t QueryCodecs(const sp<IOMX> &omx,
|
||||
const char *mimeType, bool queryDecoders,
|
||||
Vector<CodecCapabilities> *results)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "utils/RefBase.h"
|
||||
#include "utils/String16.h"
|
||||
#include "utils/String8.h"
|
||||
#include "utils/Vector.h"
|
||||
|
||||
namespace android {
|
||||
MOZ_EXPORT RefBase::RefBase() : mRefs(0)
|
||||
|
@ -54,7 +55,30 @@ MOZ_EXPORT String8::String8()
|
|||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT String8::String8(const String8 &)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT String8::~String8()
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT VectorImpl::VectorImpl(size_t, uint32_t)
|
||||
: mFlags(0), mItemSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT VectorImpl::VectorImpl(const VectorImpl &)
|
||||
: mFlags(0), mItemSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT VectorImpl::~VectorImpl()
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT void VectorImpl::finish_vector()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
@BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@omxpluginkk@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@omxpluginfroyo@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
|
||||
|
||||
|
|
|
@ -1381,6 +1381,9 @@ nsHttpConnection::OnSocketReadable()
|
|||
PRIntervalTime now = PR_IntervalNow();
|
||||
PRIntervalTime delta = now - mLastReadTime;
|
||||
|
||||
// Reset mResponseTimeoutEnabled to stop response timeout checks.
|
||||
mResponseTimeoutEnabled = false;
|
||||
|
||||
if (mKeepAliveMask && (delta >= mMaxHangTime)) {
|
||||
LOG(("max hang time exceeded!\n"));
|
||||
// give the handler a chance to create a new persistent connection to
|
||||
|
|
|
@ -23,7 +23,8 @@ XCODE_APP_STORE = 'macappstore://itunes.apple.com/app/id497799835?mt=12'
|
|||
XCODE_LEGACY = 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg'
|
||||
HOMEBREW_AUTOCONF213 = 'https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb'
|
||||
|
||||
MACPORTS_URL = {'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg',
|
||||
MACPORTS_URL = {'9': 'https://distfiles.macports.org/MacPorts/MacPorts-2.2.1-10.9-Mavericks.pkg',
|
||||
'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg',
|
||||
'7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg',
|
||||
'6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',}
|
||||
|
||||
|
|
|
@ -209,3 +209,8 @@ class WaitUntilTest(MarionetteTestCase):
|
|||
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
|
||||
|
||||
self.assertEqual(self.clock.ticks, 2)
|
||||
|
||||
def test_timeout_elapsed_duration(self):
|
||||
with self.assertRaisesRegexp(errors.TimeoutException,
|
||||
"Timed out after 2 seconds"):
|
||||
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
|
||||
|
|
|
@ -40,7 +40,7 @@ class Wait(object):
|
|||
# every 5 seconds.
|
||||
wait = Wait(marionette, timeout=30, interval=5,
|
||||
ignored_exceptions=errors.NoSuchWindowException)
|
||||
window = wait.until(lambda marionette: marionette.switch_to_window(42))
|
||||
window = wait.until(lambda m: m.switch_to_window(42))
|
||||
|
||||
:param marionette: The input value to be provided to
|
||||
conditions, usually a Marionette instance.
|
||||
|
@ -78,7 +78,6 @@ class Wait(object):
|
|||
exceptions.append(ignored_exceptions)
|
||||
self.exceptions = tuple(set(exceptions))
|
||||
|
||||
|
||||
def until(self, condition, is_true=None):
|
||||
"""Repeatedly runs condition until its return value evaluates to true,
|
||||
or its timeout expires or the predicate evaluates to true.
|
||||
|
@ -109,6 +108,7 @@ class Wait(object):
|
|||
rv = None
|
||||
last_exc = None
|
||||
until = is_true or until_pred
|
||||
start = self.clock.now
|
||||
|
||||
while not until(self.clock, self.end):
|
||||
try:
|
||||
|
@ -130,7 +130,8 @@ class Wait(object):
|
|||
if last_exc is not None:
|
||||
raise last_exc
|
||||
|
||||
raise errors.TimeoutException
|
||||
raise errors.TimeoutException(
|
||||
"Timed out after %s seconds" % (self.clock.now - start))
|
||||
|
||||
def until_pred(clock, end):
|
||||
return clock.now >= end
|
||||
|
|
|
@ -187,6 +187,8 @@
|
|||
"dom/tests/mochitest/geolocation/test_mozsettings.html": "mozSettings is undefined",
|
||||
"dom/tests/mochitest/geolocation/test_mozsettingsWatch.html": "mozSettings is undefined",
|
||||
"dom/tests/mochitest/geolocation/test_shutdown.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_timeoutWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_timerRestartWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_windowClose.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/localstorage/test_bug624047.html": "TIMED_OUT",
|
||||
|
|
|
@ -1093,7 +1093,7 @@ nsDownloadManager::GetDownloadFromDB(const nsACString& aGUID, nsDownload **retVa
|
|||
MOZ_ASSERT(!FindDownload(aGUID),
|
||||
"If it is a current download, you should not call this method!");
|
||||
|
||||
nsDependentCString query = NS_LITERAL_CSTRING(
|
||||
NS_NAMED_LITERAL_CSTRING(query,
|
||||
"SELECT id, state, startTime, source, target, tempPath, name, referrer, "
|
||||
"entityID, currBytes, maxBytes, mimeType, preferredAction, "
|
||||
"preferredApplication, autoResume, guid "
|
||||
|
|
|
@ -408,7 +408,8 @@ INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is only enabled o
|
|||
endif
|
||||
|
||||
ifdef MOZ_OMX_PLUGIN
|
||||
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginfroyo.so
|
||||
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so \
|
||||
libomxpluginhc.so libomxpluginfroyo.so libomxpluginkk.so
|
||||
endif
|
||||
|
||||
SO_LIBRARIES := $(filter %.so,$(DIST_FILES))
|
||||
|
|
|
@ -87,6 +87,7 @@ if CONFIG['MOZ_OMX_PLUGIN']:
|
|||
'media/omx-plugin/froyo',
|
||||
'media/omx-plugin/lib/hc/libstagefright',
|
||||
'media/omx-plugin/hc',
|
||||
'media/omx-plugin/kk',
|
||||
])
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
|
|
|
@ -109,7 +109,6 @@ protected:
|
|||
// to 3%-4%). See bmo bug 395397.
|
||||
static const uint32_t kHadMoreEventsCountMax = 3;
|
||||
|
||||
int32_t mRecursionDepth;
|
||||
int32_t mNativeEventCallbackDepth;
|
||||
// Can be set from different threads, so must be modified atomically
|
||||
int32_t mNativeEventScheduledDepth;
|
||||
|
|
|
@ -210,7 +210,6 @@ nsAppShell::nsAppShell()
|
|||
, mTerminated(false)
|
||||
, mSkippedNativeCallback(false)
|
||||
, mHadMoreEventsCount(0)
|
||||
, mRecursionDepth(0)
|
||||
, mNativeEventCallbackDepth(0)
|
||||
, mNativeEventScheduledDepth(0)
|
||||
{
|
||||
|
@ -712,11 +711,14 @@ nsAppShell::ProcessNextNativeEvent(bool aMayWait)
|
|||
bool
|
||||
nsAppShell::InGeckoMainEventLoop()
|
||||
{
|
||||
if ((gXULModalLevel > 0) || (mRecursionDepth > 0))
|
||||
if (gXULModalLevel > 0)
|
||||
return false;
|
||||
if (mNativeEventCallbackDepth <= 0)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
bool isProcessingEvents = false;
|
||||
NS_GetCurrentThread()->GetIsProcessingEvents(&isProcessingEvents);
|
||||
return !isProcessingEvents;
|
||||
}
|
||||
|
||||
// Run
|
||||
|
@ -818,8 +820,6 @@ nsAppShell::OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait,
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mRecursionDepth = aRecursionDepth;
|
||||
|
||||
NS_ASSERTION(mAutoreleasePools,
|
||||
"No stack on which to store autorelease pool");
|
||||
|
||||
|
@ -845,8 +845,6 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mRecursionDepth = aRecursionDepth;
|
||||
|
||||
CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
|
||||
|
||||
NS_ASSERTION(mAutoreleasePools && count,
|
||||
|
|
|
@ -66,11 +66,21 @@ stack_callback(void *pc, void *sp, void *closure)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsCocoaFeatures.h"
|
||||
#define MAC_OS_X_VERSION_10_7_HEX 0x00001070
|
||||
|
||||
static int32_t OSXVersion()
|
||||
{
|
||||
static int32_t gOSXVersion = 0x0;
|
||||
if (gOSXVersion == 0x0) {
|
||||
OSErr err = ::Gestalt(gestaltSystemVersion, (SInt32*)&gOSXVersion);
|
||||
MOZ_ASSERT(err == noErr);
|
||||
}
|
||||
return gOSXVersion;
|
||||
}
|
||||
|
||||
static bool OnLionOrLater()
|
||||
{
|
||||
return nsCocoaFeatures::OnLionOrLater();
|
||||
return (OSXVersion() >= MAC_OS_X_VERSION_10_7_HEX);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1892,8 +1892,7 @@ nsLocalFile::Launch()
|
|||
if (NS_SUCCEEDED(rv))
|
||||
rv = mimeService->GetTypeFromFile(this, type);
|
||||
|
||||
nsDependentCString fileUri = NS_LITERAL_CSTRING("file://");
|
||||
fileUri.Append(mPath);
|
||||
nsAutoCString fileUri = NS_LITERAL_CSTRING("file://") + mPath;
|
||||
return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
|
||||
#elif defined(MOZ_WIDGET_COCOA)
|
||||
CFURLRef url;
|
||||
|
|
|
@ -23,6 +23,7 @@ EXPORTS += [
|
|||
'nsSubstringTuple.h',
|
||||
'nsTDependentString.h',
|
||||
'nsTDependentSubstring.h',
|
||||
'nsTLiteralString.h',
|
||||
'nsTPromiseFlatString.h',
|
||||
'nsTString.h',
|
||||
'nsTSubstring.h',
|
||||
|
|
|
@ -16,14 +16,6 @@
|
|||
#include "nsStringIterator.h"
|
||||
#endif
|
||||
|
||||
// If some platform(s) can't handle our template that matches literal strings,
|
||||
// then we'll disable it on those platforms.
|
||||
#ifndef NS_DISABLE_LITERAL_TEMPLATE
|
||||
# if (defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x560)) || (defined(__HP_aCC) && (__HP_aCC <= 012100))
|
||||
# define NS_DISABLE_LITERAL_TEMPLATE
|
||||
# endif
|
||||
#endif /* !NS_DISABLE_LITERAL_TEMPLATE */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
|
|
@ -10,46 +10,32 @@
|
|||
#include "nscore.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsDependentString_h___
|
||||
#include "nsDependentString.h"
|
||||
#ifndef nsString_h___
|
||||
#include "nsString.h"
|
||||
#endif
|
||||
|
||||
// declare nsLiteralString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTLiteralString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsLiteralCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTLiteralString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#include "mozilla/Char16.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace internal {
|
||||
#define NS_MULTILINE_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(s))
|
||||
#define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(s)
|
||||
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsLiteralString n(s)
|
||||
|
||||
// This is the same as sizeof(c) - 1, except it won't compile if c isn't a
|
||||
// string literal. This ensures that NS_LITERAL_CSTRING doesn't compile if you
|
||||
// pass it a char* (or something else for that matter).
|
||||
template<int n>
|
||||
inline uint32_t LiteralStringLength(const char (&c)[n])
|
||||
{
|
||||
return n - 1;
|
||||
}
|
||||
#define NS_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(MOZ_UTF16(s)))
|
||||
#define NS_LITERAL_STRING_INIT(n,s) n(MOZ_UTF16(s))
|
||||
#define NS_NAMED_LITERAL_STRING(n,s) const nsLiteralString n(MOZ_UTF16(s))
|
||||
|
||||
template<int n>
|
||||
inline uint32_t LiteralWStringLength(const char16_t (&c)[n])
|
||||
{
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_MULTILINE_LITERAL_STRING(s) nsDependentString(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
|
||||
#define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
|
||||
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsDependentString n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
|
||||
typedef nsDependentString nsLiteralString;
|
||||
|
||||
#define NS_LITERAL_STRING(s) static_cast<const nsAFlatString&>(NS_MULTILINE_LITERAL_STRING(MOZ_UTF16(s)))
|
||||
#define NS_LITERAL_STRING_INIT(n,s) NS_MULTILINE_LITERAL_STRING_INIT(n, MOZ_UTF16(s))
|
||||
#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n, MOZ_UTF16(s))
|
||||
|
||||
#define NS_LITERAL_CSTRING(s) static_cast<const nsDependentCString&>(nsDependentCString(s, mozilla::internal::LiteralStringLength(s)))
|
||||
#define NS_LITERAL_CSTRING_INIT(n,s) n(s, mozilla::internal::LiteralStringLength(s))
|
||||
#define NS_NAMED_LITERAL_CSTRING(n,s) const nsDependentCString n(s, mozilla::internal::LiteralStringLength(s))
|
||||
|
||||
typedef nsDependentCString nsLiteralCString;
|
||||
#define NS_LITERAL_CSTRING(s) static_cast<const nsLiteralCString&>(nsLiteralCString(s))
|
||||
#define NS_LITERAL_CSTRING_INIT(n,s) n(s)
|
||||
#define NS_NAMED_LITERAL_CSTRING(n,s) const nsLiteralCString n(s)
|
||||
|
||||
#endif /* !defined(nsLiteralString_h___) */
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
|
||||
/**
|
||||
* nsTLiteralString_CharT
|
||||
*
|
||||
* Stores a null-terminated, immutable sequence of characters.
|
||||
*
|
||||
* Subclass of nsTString that restricts string value to a literal
|
||||
* character sequence. This class does not own its data. The data is
|
||||
* assumed to be permanent. In practice this is true because this code
|
||||
* is only usable by and for libxul.
|
||||
*/
|
||||
class nsTLiteralString_CharT : public nsTString_CharT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTLiteralString_CharT self_type;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
|
||||
template<size_type N>
|
||||
nsTLiteralString_CharT( const char_type (&str)[N] )
|
||||
: string_type(const_cast<char_type*>(str), N - 1, F_TERMINATED | F_LITERAL)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// NOT TO BE IMPLEMENTED
|
||||
template<size_type N>
|
||||
nsTLiteralString_CharT( char_type (&str)[N] ) MOZ_DELETE;
|
||||
};
|
|
@ -214,11 +214,21 @@ class nsTSubstring_CharT
|
|||
return mLength;
|
||||
}
|
||||
|
||||
uint32_t Flags() const
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return mLength == 0;
|
||||
}
|
||||
|
||||
bool IsLiteral() const
|
||||
{
|
||||
return (mFlags & F_LITERAL) != 0;
|
||||
}
|
||||
|
||||
bool IsVoid() const
|
||||
{
|
||||
return (mFlags & F_VOIDED) != 0;
|
||||
|
@ -297,24 +307,11 @@ class nsTSubstring_CharT
|
|||
// non-constant char array variable. Use EqualsASCII for them.
|
||||
// The template trick to acquire the array length at compile time without
|
||||
// using a macro is due to Corey Kosak, with much thanks.
|
||||
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
||||
inline bool EqualsLiteral( const char* str ) const
|
||||
{
|
||||
return EqualsASCII(str);
|
||||
}
|
||||
#else
|
||||
template<int N>
|
||||
inline bool EqualsLiteral( const char (&str)[N] ) const
|
||||
{
|
||||
return EqualsASCII(str, N-1);
|
||||
}
|
||||
template<int N>
|
||||
inline bool EqualsLiteral( char (&str)[N] ) const
|
||||
{
|
||||
const char* s = str;
|
||||
return EqualsASCII(s, N-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The LowerCaseEquals methods compare the ASCII-lowercase version of
|
||||
// this string (lowercasing only ASCII uppercase characters) to some
|
||||
|
@ -330,24 +327,11 @@ class nsTSubstring_CharT
|
|||
// explicit size. Do not attempt to use it with a regular char*
|
||||
// pointer, or with a non-constant char array variable. Use
|
||||
// LowerCaseEqualsASCII for them.
|
||||
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
||||
inline bool LowerCaseEqualsLiteral( const char* str ) const
|
||||
{
|
||||
return LowerCaseEqualsASCII(str);
|
||||
}
|
||||
#else
|
||||
template<int N>
|
||||
inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const
|
||||
{
|
||||
return LowerCaseEqualsASCII(str, N-1);
|
||||
}
|
||||
template<int N>
|
||||
inline bool LowerCaseEqualsLiteral( char (&str)[N] ) const
|
||||
{
|
||||
const char* s = str;
|
||||
return LowerCaseEqualsASCII(s, N-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* assignment
|
||||
|
@ -406,16 +390,13 @@ class nsTSubstring_CharT
|
|||
// non-constant char array variable. Use AssignASCII for those.
|
||||
// There are not fallible version of these methods because they only really
|
||||
// apply to small allocations that we wouldn't want to check anyway.
|
||||
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
||||
void AssignLiteral( const char* str )
|
||||
{ AssignASCII(str); }
|
||||
#else
|
||||
template<int N>
|
||||
void AssignLiteral( const char_type (&str)[N] )
|
||||
{ AssignLiteral(str, N - 1); }
|
||||
#ifdef CharT_is_PRUnichar
|
||||
template<int N>
|
||||
void AssignLiteral( const char (&str)[N] )
|
||||
{ AssignASCII(str, N-1); }
|
||||
template<int N>
|
||||
void AssignLiteral( char (&str)[N] )
|
||||
{ AssignASCII(str, N-1); }
|
||||
#endif
|
||||
|
||||
self_type& operator=( char_type c ) { Assign(c); return *this; }
|
||||
|
@ -440,6 +421,12 @@ class nsTSubstring_CharT
|
|||
|
||||
void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
|
||||
|
||||
// ReplaceLiteral must ONLY be applied to an actual literal string.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a char
|
||||
// array variable. Use Replace or ReplaceASCII for those.
|
||||
template<int N>
|
||||
void ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type (&str)[N] ) { ReplaceLiteral(cutStart, cutLength, str, N - 1); }
|
||||
|
||||
void Append( char_type c ) { Replace(mLength, 0, c); }
|
||||
void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
|
||||
|
||||
|
@ -496,17 +483,13 @@ class nsTSubstring_CharT
|
|||
|
||||
// AppendLiteral must ONLY be applied to an actual literal string.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a char
|
||||
// array variable. Use AppendASCII for those.
|
||||
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
||||
void AppendLiteral( const char* str )
|
||||
{ AppendASCII(str); }
|
||||
#else
|
||||
// array variable. Use Append or AppendASCII for those.
|
||||
template<int N>
|
||||
void AppendLiteral( const char_type (&str)[N] ) { ReplaceLiteral(mLength, 0, str, N - 1); }
|
||||
#ifdef CharT_is_PRUnichar
|
||||
template<int N>
|
||||
void AppendLiteral( const char (&str)[N] )
|
||||
{ AppendASCII(str, N-1); }
|
||||
template<int N>
|
||||
void AppendLiteral( char (&str)[N] )
|
||||
{ AppendASCII(str, N-1); }
|
||||
#endif
|
||||
|
||||
self_type& operator+=( char_type c ) { Append(c); return *this; }
|
||||
|
@ -526,6 +509,12 @@ class nsTSubstring_CharT
|
|||
void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
|
||||
void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
|
||||
|
||||
// InsertLiteral must ONLY be applied to an actual literal string.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a char
|
||||
// array variable. Use Insert for those.
|
||||
template<int N>
|
||||
void InsertLiteral( const char_type (&str)[N], index_type pos ) { ReplaceLiteral(pos, 0, str, N - 1); }
|
||||
|
||||
void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
|
||||
|
||||
|
||||
|
@ -845,6 +834,9 @@ class nsTSubstring_CharT
|
|||
mFlags = dataFlags | (mFlags & 0xFFFF0000);
|
||||
}
|
||||
|
||||
void NS_FASTCALL AssignLiteral( const char_type* data, size_type length );
|
||||
void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
|
||||
|
||||
static int AppendFunc( void* arg, const char* s, uint32_t len);
|
||||
|
||||
public:
|
||||
|
@ -865,6 +857,7 @@ class nsTSubstring_CharT
|
|||
F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
|
||||
F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
|
||||
F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
|
||||
F_LITERAL = 1 << 5, // mData points to a string literal; F_TERMINATED will also be set
|
||||
|
||||
// class flags are in the upper 16-bits
|
||||
F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
|
||||
#define nsTDependentString_CharT nsDependentCString
|
||||
#define nsTDependentSubstring_CharT nsDependentCSubstring
|
||||
#define nsTLiteralString_CharT nsLiteralCString
|
||||
#define nsTXPIDLString_CharT nsXPIDLCString
|
||||
#define nsTGetterCopies_CharT nsCGetterCopies
|
||||
#define nsTAdoptingString_CharT nsAdoptingCString
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
|
||||
#define nsTDependentString_CharT nsDependentString
|
||||
#define nsTDependentSubstring_CharT nsDependentSubstring
|
||||
#define nsTLiteralString_CharT nsLiteralString
|
||||
#define nsTXPIDLString_CharT nsXPIDLString
|
||||
#define nsTGetterCopies_CharT nsGetterCopies
|
||||
#define nsTAdoptingString_CharT nsAdoptingString
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#undef nsTDefaultStringComparator_CharT
|
||||
#undef nsTDependentString_CharT
|
||||
#undef nsTDependentSubstring_CharT
|
||||
#undef nsTLiteralString_CharT
|
||||
#undef nsTXPIDLString_CharT
|
||||
#undef nsTGetterCopies_CharT
|
||||
#undef nsTAdoptingString_CharT
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
void
|
||||
nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
|
||||
{
|
||||
NS_ABORT_IF_FALSE(str.Flags() & F_TERMINATED, "Unterminated flat string");
|
||||
|
||||
// If we currently own a buffer, release it.
|
||||
Finalize();
|
||||
|
||||
|
@ -18,5 +20,5 @@ nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
|
|||
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
|
||||
mLength = strLength - startPos;
|
||||
|
||||
SetDataFlags(F_TERMINATED);
|
||||
SetDataFlags(str.Flags() & (F_TERMINATED | F_LITERAL));
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ nsTPromiseFlatString_CharT::Init(const substring_type& str)
|
|||
{
|
||||
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data()));
|
||||
mLength = str.Length();
|
||||
mFlags = F_TERMINATED; // does not promote F_VOIDED
|
||||
mFlags = str.mFlags & (F_TERMINATED | F_LITERAL);
|
||||
// does not promote F_VOIDED
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -351,6 +351,15 @@ nsTSubstring_CharT::AssignASCII( const char* data, size_type length, const falli
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsTSubstring_CharT::AssignLiteral( const char_type* data, size_type length )
|
||||
{
|
||||
::ReleaseData(mData, mFlags);
|
||||
mData = const_cast<char_type*>(data);
|
||||
mLength = length;
|
||||
SetDataFlags(F_TERMINATED | F_LITERAL);
|
||||
}
|
||||
|
||||
void
|
||||
nsTSubstring_CharT::Assign( const self_type& str )
|
||||
{
|
||||
|
@ -391,6 +400,13 @@ nsTSubstring_CharT::Assign( const self_type& str, const fallible_t& )
|
|||
nsStringBuffer::FromData(mData)->AddRef();
|
||||
return true;
|
||||
}
|
||||
else if (str.mFlags & F_LITERAL)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(str.mFlags & F_TERMINATED, "Unterminated literal");
|
||||
|
||||
AssignLiteral(str.mData, str.mLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
// else, treat this like an ordinary assignment.
|
||||
return Assign(str.Data(), str.Length(), fallible_t());
|
||||
|
@ -536,6 +552,17 @@ nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const sub
|
|||
tuple.WriteTo(mData + cutStart, length);
|
||||
}
|
||||
|
||||
void
|
||||
nsTSubstring_CharT::ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
|
||||
{
|
||||
cutStart = XPCOM_MIN(cutStart, Length());
|
||||
|
||||
if (!cutStart && cutLength == Length())
|
||||
AssignLiteral(data, length);
|
||||
else if (ReplacePrep(cutStart, cutLength, length) && length > 0)
|
||||
char_traits::copy(mData + cutStart, data, length);
|
||||
}
|
||||
|
||||
void
|
||||
nsTSubstring_CharT::SetCapacity( size_type capacity )
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ interface nsIGeolocationPrompt;
|
|||
* Interface provides a way for a geolocation provider to
|
||||
* notify the system that a new location is available.
|
||||
*/
|
||||
[scriptable, uuid(f00ff730-acff-4e8c-9991-0d4c84ba0e10)]
|
||||
[scriptable, uuid(643dc5e9-b911-4b2c-8d44-603162696baf)]
|
||||
interface nsIGeolocationUpdate : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,13 @@ interface nsIGeolocationUpdate : nsISupports {
|
|||
*/
|
||||
void update(in nsIDOMGeoPosition position);
|
||||
|
||||
/**
|
||||
* Notify the geolocation service that the location has
|
||||
* potentially changed, and thus a new position is in the
|
||||
* process of being acquired.
|
||||
*/
|
||||
void locationUpdatePending();
|
||||
|
||||
/**
|
||||
* Notify the geolocation service of an error.
|
||||
* This must be called on the main thread.
|
||||
|
|
|
@ -462,6 +462,17 @@ LazyIdleThread::ProcessNextEvent(bool aMayWait,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LazyIdleThread::GetIsProcessingEvents(bool* aIsProcessing)
|
||||
{
|
||||
if (mThread) {
|
||||
return mThread->GetIsProcessingEvents(aIsProcessing);
|
||||
}
|
||||
|
||||
*aIsProcessing = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LazyIdleThread::Notify(nsITimer* aTimer)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* See nsIThreadManager for the API used to create and locate threads.
|
||||
*/
|
||||
[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)]
|
||||
[scriptable, uuid(4df07d3a-e759-4256-ba4e-7e2265354ec3)]
|
||||
interface nsIThread : nsIEventTarget
|
||||
{
|
||||
/**
|
||||
|
@ -82,4 +82,10 @@ interface nsIThread : nsIEventTarget
|
|||
* not the current thread.
|
||||
*/
|
||||
boolean processNextEvent(in boolean mayWait);
|
||||
|
||||
/**
|
||||
* true if we're processing runnables or thread observers and if this is the
|
||||
* current thread.
|
||||
*/
|
||||
readonly attribute boolean isProcessingEvents;
|
||||
};
|
||||
|
|
|
@ -304,6 +304,7 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize)
|
|||
, mThread(nullptr)
|
||||
, mRunningEvent(0)
|
||||
, mStackSize(aStackSize)
|
||||
, mProcessingEvent(0)
|
||||
, mShutdownContext(nullptr)
|
||||
, mShutdownRequired(false)
|
||||
, mEventsAreDoomed(false)
|
||||
|
@ -596,6 +597,8 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
|||
}
|
||||
}
|
||||
|
||||
++mProcessingEvent;
|
||||
|
||||
bool notifyMainThreadObserver =
|
||||
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
|
||||
if (notifyMainThreadObserver)
|
||||
|
@ -650,9 +653,22 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
|||
if (notifyMainThreadObserver && sMainThreadObserver)
|
||||
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);
|
||||
|
||||
--mProcessingEvent;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThread::GetIsProcessingEvents(bool* aIsProcessing)
|
||||
{
|
||||
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
*aIsProcessing = mProcessingEvent != 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupportsPriority
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ protected:
|
|||
uint32_t mRunningEvent; // counter
|
||||
uint32_t mStackSize;
|
||||
|
||||
uint32_t mProcessingEvent;
|
||||
|
||||
struct nsThreadShutdownContext *mShutdownContext;
|
||||
|
||||
bool mShutdownRequired;
|
||||
|
|
Загрузка…
Ссылка в новой задаче