Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-02-27 15:59:39 +01:00
Родитель 35e512d271 b3d9738274
Коммит 01f93d64ea
520 изменённых файлов: 6253 добавлений и 2441 удалений

Просмотреть файл

@ -17,7 +17,7 @@
#include "nsIChannel.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsISelectionPrivate.h"
#include "nsTraceRefcntImpl.h"
#include "nsTraceRefcnt.h"
#include "nsIWebProgress.h"
#include "prenv.h"
#include "nsIDocShellTreeItem.h"
@ -800,7 +800,7 @@ logging::Stack()
{
if (IsEnabled(eStack)) {
printf(" stack: \n");
nsTraceRefcntImpl::WalkTheStack(stdout);
nsTraceRefcnt::WalkTheStack(stdout);
}
}

Просмотреть файл

@ -433,6 +433,15 @@ this.Logger = {
str += ' (' + stateStrings.item(0) + ')';
}
if (aEvent.eventType == Events.VIRTUALCURSOR_CHANGED) {
let event = aEvent.QueryInterface(
Ci.nsIAccessibleVirtualCursorChangeEvent);
let pivot = aEvent.accessible.QueryInterface(
Ci.nsIAccessibleDocument).virtualCursor;
str += ' (' + this.accessibleToString(event.oldAccessible) + ' -> ' +
this.accessibleToString(pivot.position) + ')';
}
return str;
},

Просмотреть файл

@ -400,6 +400,8 @@ addMessageListener(
eventManager = new EventManager(this);
}
eventManager.start();
sendAsyncMessage('AccessFu:ContentStarted');
});
addMessageListener(

Просмотреть файл

@ -3,8 +3,10 @@ support-files =
jsatcommon.js
output.js
doc_traversal.html
doc_content_integration.html
[test_alive.html]
[test_content_integration.html]
[test_explicit_names.html]
[test_landmarks.html]
[test_live_regions.html]

Просмотреть файл

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>Traversal Rule test document</title>
<meta charset="utf-8" />
<script>
var frameContents = '<html>' +
'<head><title>such app</title></head>' +
'<body>' +
'<h1>wow</h1>' +
'<label><input type="checkbox">many option</label>' +
'</body>' +
'</html>';
</script>
<style>
#windows > iframe {
width: 320px;
height: 480px;
}
</style>
</head>
<body>
<div>Phone status bar</div>
<div id="windows"></div>
<button>Home</button>
</body>
</html>

Просмотреть файл

@ -155,3 +155,117 @@ var AccessFuTest = {
SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 1);
}
};
function AccessFuContentTest(aFuncResultPairs) {
this.queue = aFuncResultPairs;
}
AccessFuContentTest.prototype = {
currentPair: null,
start: function(aFinishedCallback) {
this.finishedCallback = aFinishedCallback;
var self = this;
// Get top content message manager, and set it up.
this.mms = [Utils.getMessageManager(currentBrowser())];
this.setupMessageManager(this.mms[0], function () {
// Get child message managers and set them up
var frames = currentTabDocument().querySelectorAll('iframe');
var toSetup = 0;
for (var i = 0; i < frames.length; i++ ) {
var mm = Utils.getMessageManager(frames[i]);
if (mm) {
toSetup++;
self.mms.push(mm);
self.setupMessageManager(mm, function () {
if (--toSetup === 0) {
// All message managers are loaded and ready to go.
self.pump();
}
});
}
}
});
},
setupMessageManager: function (aMessageManager, aCallback) {
function contentScript() {
addMessageListener('AccessFuTest:Focus', function (aMessage) {
var elem = content.document.querySelector(aMessage.json.selector);
if (elem) {
if (aMessage.json.blur) {
elem.blur();
} else {
elem.focus();
}
}
});
}
aMessageManager.addMessageListener('AccessFu:Present', this);
aMessageManager.addMessageListener('AccessFu:Ready', function (aMessage) {
aMessageManager.addMessageListener('AccessFu:ContentStarted', aCallback);
aMessageManager.sendAsyncMessage('AccessFu:Start', { buildApp: 'browser' });
});
aMessageManager.loadFrameScript(
'chrome://global/content/accessibility/content-script.js', false);
aMessageManager.loadFrameScript(
'data:,(' + contentScript.toString() + ')();', false);
},
pump: function() {
this.currentPair = this.queue.shift();
if (this.currentPair) {
if (this.currentPair[0] instanceof Function) {
this.currentPair[0](this.mms[0]);
} else {
this.mms[0].sendAsyncMessage(this.currentPair[0].name,
this.currentPair[0].json);
}
} else if (this.finishedCallback) {
for (var mm of this.mms) {
mm.sendAsyncMessage('AccessFu:Stop');
}
this.finishedCallback();
}
},
receiveMessage: function(aMessage) {
if (!this.currentPair) {
return;
}
var expected = this.currentPair[1];
if (expected) {
if (expected.speak !== undefined) {
var speech = this.extractUtterance(aMessage.json);
if (!speech) {
// Probably a visual highlight adjustment after a scroll.
return;
}
var checkFunc = SimpleTest[expected.speak_checkFunc] || is;
checkFunc(speech, expected.speak);
}
}
this.pump();
},
extractUtterance: function(aData) {
for (var output of aData) {
if (output && output.type === 'Speech') {
for (var action of output.details.actions) {
if (action && action.method == 'speak') {
return action.data;
}
}
}
}
return null;
}
};

Просмотреть файл

@ -0,0 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<title>Tests AccessFu content integration</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
</script>
<script type="application/javascript"
src="chrome://mochikit/content/chrome-harness.js">
</script>
<script type="application/javascript" src="../common.js"></script>
<script type="application/javascript" src="../browser.js"></script>
<script type="application/javascript" src="../events.js"></script>
<script type="application/javascript" src="../role.js"></script>
<script type="application/javascript" src="../states.js"></script>
<script type="application/javascript" src="../layout.js"></script>
<script type="application/javascript" src="jsatcommon.js"></script>
<script type="application/javascript">
function doTest() {
var doc = currentTabDocument();
var iframe = doc.createElement("iframe");
iframe.mozbrowser = true;
iframe.addEventListener("mozbrowserloadend", function () {
var simpleMoveNext = { name: 'AccessFu:MoveCursor',
json: { action: 'moveNext',
rule: 'Simple',
inputType: 'gesture',
origin: 'top' }
};
var simpleMovePrevious = { name: 'AccessFu:MoveCursor',
json: { action: 'movePrevious',
rule: 'Simple',
inputType: 'gesture',
origin: 'top' }
};
var activateCurrent = { name: 'AccessFu:Activate',
json: { origin: 'top' } };
var simpleMoveLast = { name: 'AccessFu:MoveCursor',
json: { action: 'moveLast',
rule: 'Simple',
inputType: 'gesture',
origin: 'top' }
};
var simpleMoveFirst = { name: 'AccessFu:MoveCursor',
json: { action: 'moveFirst',
rule: 'Simple',
inputType: 'gesture',
origin: 'top' }
};
var clearCursor = { name: 'AccessFu:ClearCursor',
json: { origin: 'top' }
};
function focusFunc(aSelector, aBlur) {
return function (mm) {
mm.sendAsyncMessage(
'AccessFuTest:Focus', { selector: aSelector, blur: aBlur });
};
}
var contentTest = new AccessFuContentTest(
[
// Simple traversal forward
[simpleMoveNext,
{ speak: 'Phone status bar Traversal Rule test document' }],
[simpleMoveNext,
{ speak: 'wow heading level 1 such app' }],
[simpleMoveNext,
{ speak: 'many option not checked check button' }],
// check checkbox
[activateCurrent,
{ speak: 'checked' }],
[null,
{ speak: 'checked', speak_checkFunc: 'todo_isnot' }],
// uncheck checkbox
[simpleMoveNext,
{ speak: 'Home button' }],
// Simple traversal backward
[simpleMovePrevious,
{ speak: 'many option checked check button such app' }],
[activateCurrent,
{ speak: 'unchecked' }],
[null,
{ speak: 'unchecked', speak_checkFunc: 'todo_isnot' }],
[simpleMovePrevious,
{ speak: 'wow heading level 1' }],
[simpleMovePrevious,
{ speak: 'Phone status bar' }],
// Moving to the absolute last item from an embedded document fails.
// Bug 972035.
[simpleMoveNext,
{ speak: 'wow heading level 1 such app' }],
// Move from an inner frame to the last element in the parent doc
[simpleMoveLast,
{ speak: 'Home button', speak_checkFunc: 'todo_is' }],
[clearCursor, null], // Reset cursors
// Moving to the absolute first item from an embedded document fails.
// Bug 972035.
[simpleMoveNext,
{ speak: 'Phone status bar Traversal Rule test document' }],
[simpleMoveNext,
{ speak: 'wow heading level 1 such app' }],
[simpleMoveNext,
{ speak: 'many option not checked check button' }],
[simpleMoveFirst,
{ speak: 'Phone status bar', speak_checkFunc: 'todo_is' }],
// Reset cursors
[clearCursor, null],
// Move cursor with focus in outside document
[simpleMoveNext,
{ speak: 'Phone status bar Traversal Rule test document' }],
[ focusFunc('button', false), { speak: 'Home button' }],
// Blur button and reset cursor
[focusFunc('button', true), null],
[clearCursor, null],
// Set focus on element outside of embedded frame while cursor is in frame
[simpleMoveNext,
{ speak: 'Phone status bar Traversal Rule test document' }],
[simpleMoveNext,
{ speak: 'wow heading level 1 such app' }],
[focusFunc('button', false), { speak: 'Home button' }]
// XXX: Set focus on iframe itself.
// XXX: Set focus on element in iframe when cursor is outside of it.
// XXX: Set focus on element in iframe when cursor is in iframe.
]);
contentTest.start(function () {
closeBrowserWindow();
SimpleTest.finish();
});
});
iframe.src = 'data:text/html;charset=utf-8,' + doc.defaultView.frameContents;
doc.querySelector('#windows').appendChild(iframe);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(
function () {
openBrowserWindow(
function () {
SpecialPowers.pushPrefEnv({
"set": [
// TODO: remove this as part of bug 820712
["network.disable.ipc.security", true],
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, doTest) },
getRootDirectory(window.location.href) + "doc_content_integration.html");
});
</script>
</head>
<body id="body">
<a target="_blank"
title="Add tests for OOP message handling and general integration"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=972047">Mozilla Bug 933808</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -26,7 +26,6 @@ LIBS += \
-lsuspend \
$(NULL)
endif
OS_LDFLAGS += -Wl,--export-dynamic
endif
STL_FLAGS=

Просмотреть файл

@ -39,3 +39,5 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
LOCAL_INCLUDES += [
'/widget/gonk/libdisplay',
]
LDFLAGS += ['-Wl,--export-dynamic']

Просмотреть файл

@ -4,29 +4,36 @@
'use strict';
const WIDGET_PANEL_LOG_PREFIX = 'WidgetPanel';
const DEVELOPER_HUD_LOG_PREFIX = 'DeveloperHUD';
XPCOMUtils.defineLazyGetter(this, 'devtools', function() {
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
return devtools;
});
XPCOMUtils.defineLazyGetter(this, 'DebuggerClient', function() {
return Cu.import('resource://gre/modules/devtools/dbg-client.jsm', {}).DebuggerClient;
});
XPCOMUtils.defineLazyGetter(this, 'WebConsoleUtils', function() {
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
return devtools.require("devtools/toolkit/webconsole/utils").Utils;
});
XPCOMUtils.defineLazyGetter(this, 'EventLoopLagFront', function() {
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
return devtools.require("devtools/server/actors/eventlooplag").EventLoopLagFront;
});
XPCOMUtils.defineLazyGetter(this, 'MemoryFront', function() {
return devtools.require("devtools/server/actors/memory").MemoryFront;
});
/**
* The Widget Panel is an on-device developer tool that displays widgets,
* The Developer HUD is an on-device developer tool that displays widgets,
* showing visual debug information about apps. Each widget corresponds to a
* metric as tracked by a metric watcher (e.g. consoleWatcher).
*/
let devtoolsWidgetPanel = {
let developerHUD = {
_apps: new Map(),
_urls: new Map(),
@ -107,7 +114,7 @@ let devtoolsWidgetPanel = {
if (this._apps.has(manifestURL))
return;
// FIXME(Bug 962577) Factor getAppActor and watchApps out of webappsActor.
// FIXME(Bug 962577) Factor getAppActor out of webappsActor.
this._client.request({
to: this._webappsActor,
type: 'getAppActor',
@ -179,7 +186,7 @@ let devtoolsWidgetPanel = {
},
log: function dwp_log(message) {
dump(WIDGET_PANEL_LOG_PREFIX + ': ' + message + '\n');
dump(DEVELOPER_HUD_LOG_PREFIX + ': ' + message + '\n');
}
};
@ -208,7 +215,7 @@ App.prototype = {
}
}
shell.sendCustomEvent('widget-panel-update', data);
shell.sendCustomEvent('developer-hud-update', data);
// FIXME(after bug 963239 lands) return event.isDefaultPrevented();
return false;
}
@ -238,9 +245,9 @@ let consoleWatcher = {
for (let key in watching) {
let metric = key;
SettingsListener.observe('devtools.hud.' + metric, false, value => {
SettingsListener.observe('hud.' + metric, false, watch => {
// Watch or unwatch the metric.
if (watching[metric] = value) {
if (watching[metric] = watch) {
return;
}
@ -356,7 +363,7 @@ let consoleWatcher = {
if (!app.display()) {
// If the information was not displayed, log it.
devtoolsWidgetPanel.log(output);
developerHUD.log(output);
}
},
@ -372,11 +379,10 @@ let consoleWatcher = {
return source;
}
};
devtoolsWidgetPanel.registerWatcher(consoleWatcher);
developerHUD.registerWatcher(consoleWatcher);
let jankWatcher = {
let eventLoopLagWatcher = {
_client: null,
_fronts: new Map(),
_active: false,
@ -384,8 +390,7 @@ let jankWatcher = {
init: function(client) {
this._client = client;
SettingsListener.observe('devtools.hud.jank', false,
this.settingsListener.bind(this));
SettingsListener.observe('hud.jank', false, this.settingsListener.bind(this));
},
settingsListener: function(value) {
@ -417,7 +422,7 @@ let jankWatcher = {
app.metrics.set('jank', time);
if (!app.display()) {
devtoolsWidgetPanel.log('jank: ' + time + 'ms');
developerHUD.log('jank: ' + time + 'ms');
}
});
@ -434,5 +439,108 @@ let jankWatcher = {
}
}
};
developerHUD.registerWatcher(eventLoopLagWatcher);
devtoolsWidgetPanel.registerWatcher(jankWatcher);
/**
* The Memory Watcher uses devtools actors to track memory usage.
*/
let memoryWatcher = {
_client: null,
_fronts: new Map(),
_timers: new Map(),
_watching: {
jsobjects: false,
jsstrings: false,
jsother: false,
dom: false,
style: false,
other: false
},
_active: false,
init: function mw_init(client) {
this._client = client;
let watching = this._watching;
for (let key in watching) {
let category = key;
SettingsListener.observe('hud.' + category, false, watch => {
watching[category] = watch;
});
}
SettingsListener.observe('hud.appmemory', false, enabled => {
if (this._active = enabled) {
for (let app of this._fronts.keys()) {
this.measure(app);
}
} else {
for (let timer of this._timers.values()) {
clearTimeout(this._timers.get(app));
}
}
});
},
measure: function mw_measure(app) {
// TODO Also track USS (bug #976024).
let watch = this._watching;
let front = this._fronts.get(app);
front.measure().then((data) => {
let total = 0;
if (watch.jsobjects) {
total += parseInt(data.jsObjectsSize);
}
if (watch.jsstrings) {
total += parseInt(data.jsStringsSize);
}
if (watch.jsother) {
total += parseInt(data.jsOtherSize);
}
if (watch.dom) {
total += parseInt(data.domSize);
}
if (watch.style) {
total += parseInt(data.styleSize);
}
if (watch.other) {
total += parseInt(data.otherSize);
}
// TODO Also count images size (bug #976007).
app.metrics.set('memory', total);
app.display();
let duration = parseInt(data.jsMilliseconds) + parseInt(data.nonJSMilliseconds);
let timer = setTimeout(() => this.measure(app), 100 * duration);
this._timers.set(app, timer);
}, (err) => {
console.error(err);
});
},
trackApp: function mw_trackApp(app) {
app.metrics.set('uss', 0);
app.metrics.set('memory', 0);
this._fronts.set(app, MemoryFront(this._client, app.actor));
if (this._active) {
this.measure(app);
}
},
untrackApp: function mw_untrackApp(app) {
let front = this._fronts.get(app);
if (front) {
front.destroy();
clearTimeout(this._timers.get(app));
this._fronts.delete(app);
this._timers.delete(app);
}
}
};
developerHUD.registerWatcher(memoryWatcher);

Просмотреть файл

@ -219,18 +219,18 @@ Components.utils.import('resource://gre/modules/ctypes.jsm');
// =================== DevTools ====================
let devtoolsWidgetPanel;
let developerHUD;
SettingsListener.observe('devtools.overlay', false, (value) => {
if (value) {
if (!devtoolsWidgetPanel) {
if (!developerHUD) {
let scope = {};
Services.scriptloader.loadSubScript('chrome://b2g/content/devtools.js', scope);
devtoolsWidgetPanel = scope.devtoolsWidgetPanel;
developerHUD = scope.developerHUD;
}
devtoolsWidgetPanel.init();
developerHUD.init();
} else {
if (devtoolsWidgetPanel) {
devtoolsWidgetPanel.uninit();
if (developerHUD) {
developerHUD.uninit();
}
}
});

Просмотреть файл

@ -26,6 +26,7 @@ MOZ_WEBSMS_BACKEND=1
MOZ_DISABLE_CRYPTOLEGACY=1
MOZ_APP_STATIC_INI=1
NSS_NO_LIBPKIX=1
MOZ_NO_EV_CERTS=1
MOZ_DISABLE_EXPORT_JS=1
if test "$OS_TARGET" = "Android"; then

Просмотреть файл

@ -67,22 +67,6 @@ PROGRAMS_DEST = $(DIST)/bin
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),WINNT) #{
#
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
#
# The default heap size is 1MB on Win32.
# The heap will grow if need be.
#
# Set it to 256k. See bug 127069.
#
ifndef GNU_CC #{
LDFLAGS += /HEAP:0x40000
endif #}
endif #}
ifneq (,$(filter-out WINNT,$(OS_ARCH)))
ifdef COMPILE_ENVIRONMENT

Просмотреть файл

@ -40,3 +40,14 @@ if CONFIG['_MSC_VER']:
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['MOZ_PHOENIX'] = True
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
#
# The default heap size is 1MB on Win32.
# The heap will grow if need be.
#
# Set it to 256k. See bug 127069.
if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']:
LDFLAGS += ['/HEAP:0x40000']

Просмотреть файл

@ -77,13 +77,20 @@ function promiseMessage(aMessage, aAction) {
return deferred.promise;
}
function promisePopupNotification(aName) {
function promisePopupNotification(aName, aShown) {
let deferred = Promise.defer();
waitForCondition(() => PopupNotifications.getNotification(aName),
// If aShown is true, the notification is expected to be opened by
// default and we wait for the panel to be populated; for dismissed
// notifications, we are happy as soon as we find the icon.
waitForCondition(() => PopupNotifications.getNotification(aName) &&
(!aShown || PopupNotifications.panel.firstChild),
() => {
ok(!!PopupNotifications.getNotification(aName),
aName + " notification appeared");
if (aShown)
ok(PopupNotifications.panel.firstChild, "notification panel populated");
deferred.resolve();
}, "timeout waiting for popup notification " + aName);
@ -205,7 +212,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
yield promiseMessage("ok", () => {
@ -229,7 +236,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true);
yield promiseMessage("ok", () => {
@ -252,7 +259,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(false, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(false, true);
yield promiseMessage("ok", () => {
@ -275,7 +282,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
// disable the camera
@ -306,7 +313,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
// disable the microphone
@ -337,7 +344,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
// disable the camera and microphone
@ -366,7 +373,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
yield promiseMessage("error: PERMISSION_DENIED", () => {
@ -387,7 +394,7 @@ let gTests = [
content.wrappedJSObject.requestDevice(true, true);
});
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
checkDeviceSelectors(true, true);
yield promiseMessage("ok", () => {
@ -424,15 +431,15 @@ let gTests = [
{
desc: "getUserMedia prompt: Always/Never Share",
run: function checkRememberCheckbox() {
let elt = id => document.getElementById(id);
function checkPerm(aRequestAudio, aRequestVideo, aAllowAudio, aAllowVideo,
aExpectedAudioPerm, aExpectedVideoPerm, aNever) {
yield promiseNotification("getUserMedia:request", () => {
content.wrappedJSObject.requestDevice(aRequestAudio, aRequestVideo);
});
yield promisePopupNotification("webRTC-shareDevices");
let elt = id => document.getElementById(id);
yield promisePopupNotification("webRTC-shareDevices", true);
let noAudio = aAllowAudio === undefined;
is(elt("webRTC-selectMicrophone").hidden, noAudio,
@ -519,6 +526,10 @@ let gTests = [
info("audio+video, user denies audio, grants video, " +
"expect video perm set to allow, audio perm set to deny.");
yield checkPerm(true, true, false, true, false, true);
// reset the menuitems to have no impact on the following tests.
elt("webRTC-selectMicrophone-menulist").value = 0;
elt("webRTC-selectCamera-menulist").value = 0;
}
},
@ -545,7 +556,7 @@ let gTests = [
if (aExpectStream === undefined) {
// Check that we get a prompt.
yield promiseNotification("getUserMedia:request", gum);
yield promisePopupNotification("webRTC-shareDevices");
yield promisePopupNotification("webRTC-shareDevices", true);
// Deny the request to cleanup...
yield promiseMessage("error: PERMISSION_DENIED", () => {

Просмотреть файл

@ -492,24 +492,8 @@ function sendDragEvent(aEventType, aTarget, aData) {
* @return The drag event.
*/
function createDragEvent(aEventType, aData) {
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () aData,
types: {
contains: function (aType) aType == "text/x-moz-url"
},
mozGetDataAt: function (aType, aIndex) {
if (aIndex || aType != "text/x-moz-url")
return null;
return aData;
}
};
let dataTransfer = new getContentWindow().DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", aData, 0);
let event = getContentDocument().createEvent("DragEvents");
event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

Просмотреть файл

@ -678,8 +678,8 @@ const CustomizableWidgets = [{
let elem = aDocument.createElementNS(kNSXUL, "toolbarbutton");
elem.setAttribute("label", item.label);
elem.setAttribute("type", "checkbox");
elem.section = aSection == "detectors" ? "detectors" : "charsets";
elem.value = item.id;
elem.section = aSection;
elem.value = item.value;
elem.setAttribute("class", "subviewbutton");
containerElem.appendChild(elem);
}
@ -687,10 +687,7 @@ const CustomizableWidgets = [{
updateCurrentCharset: function(aDocument) {
let content = aDocument.defaultView.content;
let currentCharset = content && content.document && content.document.characterSet;
if (currentCharset) {
currentCharset = aDocument.defaultView.FoldCharset(currentCharset);
}
currentCharset = currentCharset ? ("charset." + currentCharset) : "";
currentCharset = CharsetMenu.foldCharset(currentCharset);
let pinnedContainer = aDocument.getElementById("PanelUI-characterEncodingView-pinned");
let charsetContainer = aDocument.getElementById("PanelUI-characterEncodingView-charsets");
@ -700,13 +697,11 @@ const CustomizableWidgets = [{
},
updateCurrentDetector: function(aDocument) {
let detectorContainer = aDocument.getElementById("PanelUI-characterEncodingView-autodetect");
let detectorEnum = CharsetManager.GetCharsetDetectorList();
let currentDetector;
try {
currentDetector = Services.prefs.getComplexValue(
"intl.charset.detector", Ci.nsIPrefLocalizedString).data;
} catch (e) {}
currentDetector = "chardet." + (currentDetector || "off");
this._updateElements(detectorContainer.childNodes, currentDetector);
},
@ -762,13 +757,8 @@ const CustomizableWidgets = [{
// The behavior as implemented here is directly based off of the
// `MultiplexHandler()` method in browser.js.
if (section != "detectors") {
let charset = value.substring(value.indexOf('charset.') + 'charset.'.length);
window.BrowserSetForcedCharacterSet(charset);
window.BrowserSetForcedCharacterSet(value);
} else {
value = value.replace(/^chardet\./, "");
if (value == "off") {
value = "";
}
// Set the detector pref.
try {
let str = Cc["@mozilla.org/supports-string;1"]

Просмотреть файл

@ -85,7 +85,7 @@ let gSyncPane = {
_init: function () {
let topics = ["weave:service:login:error",
"weave:service:login:finish",
"weave:service:start-over",
"weave:service:start-over:finish",
"weave:service:setup-complete",
"weave:service:logout:finish",
FxAccountsCommon.ONVERIFIED_NOTIFICATION];

Просмотреть файл

@ -3140,12 +3140,8 @@ let SessionStoreInternal = {
*/
_prepDataForDeferredRestore: function ssi_prepDataForDeferredRestore(state) {
// Make sure that we don't modify the global state as provided by
// nsSessionStartup.state. Converting the object to a JSON string and
// parsing it again is the easiest way to do that, although not the most
// efficient one. Deferred sessions that don't have automatic session
// restore enabled tend to be a lot smaller though so that this shouldn't
// be a big perf hit.
state = JSON.parse(JSON.stringify(state));
// nsSessionStartup.state.
state = Cu.cloneInto(state, {});
let defaultState = { windows: [], selectedWindow: 1 };

Просмотреть файл

@ -20,6 +20,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabStateCache",
"resource:///modules/sessionstore/TabStateCache.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TabAttributes",
"resource:///modules/sessionstore/TabAttributes.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource:///modules/sessionstore/Utils.jsm");
/**
* Module that contains tab state collection methods.
@ -151,7 +153,7 @@ let TabStateInternal = {
// Use the data to be restored when the tab hasn't been
// completely loaded. We clone the data, since we're updating it
// here and the caller may update it further.
tabData = JSON.parse(JSON.stringify(browser.__SS_data));
tabData = Utils.shallowCopy(browser.__SS_data);
if (tab.pinned)
tabData.pinned = true;
else

Просмотреть файл

@ -41,5 +41,15 @@ this.Utils = Object.freeze({
let prevChar = host[index - 1];
return (index == (host.length - domain.length)) &&
(prevChar == "." || prevChar == "/");
},
shallowCopy: function (obj) {
let retval = {};
for (let key of Object.keys(obj)) {
retval[key] = obj[key];
}
return retval;
}
});

Просмотреть файл

@ -2128,16 +2128,6 @@ Breakpoints.prototype = {
}
},
/**
* Gets all Promises for the BreakpointActor client objects that are
* either enabled (added to the server) or disabled (removed from the server,
* but for which some details are preserved).
*/
get _addedOrDisabled() {
for (let [, value] of this._added) yield value;
for (let [, value] of this._disabled) yield value;
},
/**
* Get a Promise for the BreakpointActor client object which is already added
* or currently being added at the given location.
@ -2180,6 +2170,22 @@ Breakpoints.prototype = {
}
};
/**
* Gets all Promises for the BreakpointActor client objects that are
* either enabled (added to the server) or disabled (removed from the server,
* but for which some details are preserved).
*/
Object.defineProperty(Breakpoints.prototype, "_addedOrDisabled", {
get: function* () {
for (let [, value] of this._added) {
yield value;
}
for (let [, value] of this._disabled) {
yield value;
}
}
});
/**
* Localization convenience methods.
*/

Просмотреть файл

@ -22,11 +22,13 @@ The sourceeditor component contains imported CodeMirror tests [3].
* Some tests were commented out because we don't use that functionality
within Firefox (for example Ruby editing mode). Be careful when updating
files test/codemirror.html and test/vimemacs.html; they were modified to
co-exist with Mozilla's testing infrastructure.
co-exist with Mozilla's testing infrastructure. Basically, vimemacs.html
is a copy of codemirror.html but only with VIM and Emacs mode tests
enabled.
* In cm_comment_test.js comment out fallbackToBlock and fallbackToLine
tests.
* The search addon (search.js) was slightly modified to make search
UI localizable.
UI localizable (see patch below).
Other than that, we don't have any Mozilla-specific patches applied to
CodeMirror itself.
@ -76,6 +78,38 @@ in the LICENSE file:
* test/cm_emacs_test.js
* test/cm_test.js
# Localization patches
diff --git a/browser/devtools/sourceeditor/codemirror/search/search.js b/browser/devtools/sourceeditor/codemirror/sea
index 049f72f..df4d95e 100644
--- a/browser/devtools/sourceeditor/codemirror/search/search.js
+++ b/browser/devtools/sourceeditor/codemirror/search/search.js
@@ -58,9 +58,22 @@
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
}
- var queryDialog =
- 'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)<
+ var queryDialog;
function doSearch(cm, rev) {
+ if (!queryDialog) {
+ let doc = cm.getWrapperElement().ownerDocument;
+ let inp = doc.createElement("input");
+ let txt = doc.createTextNode(cm.l10n("findCmd.promptMessage"));
+
+ inp.type = "text";
+ inp.style.width = "10em";
+ inp.style.MozMarginStart = "1em";
+
+ queryDialog = doc.createElement("div");
+ queryDialog.appendChild(txt);
+ queryDialog.appendChild(inp);
+ }
+
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
# Footnotes
[1] http://codemirror.net

Просмотреть файл

@ -58,9 +58,22 @@
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
}
var queryDialog =
'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
var queryDialog;
function doSearch(cm, rev) {
if (!queryDialog) {
let doc = cm.getWrapperElement().ownerDocument;
let inp = doc.createElement("input");
let txt = doc.createTextNode(cm.l10n("findCmd.promptMessage"));
inp.type = "text";
inp.style.width = "10em";
inp.style.MozMarginStart = "1em";
queryDialog = doc.createElement("div");
queryDialog.appendChild(txt);
queryDialog.appendChild(inp);
}
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {

Просмотреть файл

@ -775,6 +775,7 @@ Editor.prototype = {
setFontSize: function (size) {
let cm = editors.get(this);
cm.getWrapperElement().style.fontSize = parseInt(size, 10) + "px";
cm.refresh();
},
/**

Просмотреть файл

@ -26,6 +26,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
const UITOUR_PERMISSION = "uitour";
const PREF_PERM_BRANCH = "browser.uitour.";
const PREF_SEENPAGEIDS = "browser.uitour.seenPageIDs";
const MAX_BUTTONS = 4;
const BUCKET_NAME = "UITour";
@ -36,10 +37,12 @@ const BUCKET_TIMESTEPS = [
60 * 60 * 1000, // Until 1 hour after tab is closed/inactive.
];
// Time after which seen Page IDs expire.
const SEENPAGEID_EXPIRY = 2 * 7 * 24 * 60 * 60 * 1000; // 2 weeks.
this.UITour = {
seenPageIDs: new Set(),
seenPageIDs: null,
pageIDSourceTabs: new WeakMap(),
pageIDSourceWindows: new WeakMap(),
/* Map from browser windows to a set of tabs in which a tour is open */
@ -115,10 +118,72 @@ this.UITour = {
]),
init: function() {
// Lazy getter is initialized here so it can be replicated any time
// in a test.
delete this.seenPageIDs;
Object.defineProperty(this, "seenPageIDs", {
get: this.restoreSeenPageIDs.bind(this),
configurable: true,
});
UITelemetry.addSimpleMeasureFunction("UITour",
this.getTelemetry.bind(this));
},
restoreSeenPageIDs: function() {
delete this.seenPageIDs;
if (UITelemetry.enabled) {
let dateThreshold = Date.now() - SEENPAGEID_EXPIRY;
try {
let data = Services.prefs.getCharPref(PREF_SEENPAGEIDS);
data = new Map(JSON.parse(data));
for (let [pageID, details] of data) {
if (typeof pageID != "string" ||
typeof details != "object" ||
typeof details.lastSeen != "number" ||
details.lastSeen < dateThreshold) {
data.delete(pageID);
}
}
this.seenPageIDs = data;
} catch (e) {}
}
if (!this.seenPageIDs)
this.seenPageIDs = new Map();
this.persistSeenIDs();
return this.seenPageIDs;
},
addSeenPageID: function(aPageID) {
if (!UITelemetry.enabled)
return;
this.seenPageIDs.set(aPageID, {
lastSeen: Date.now(),
});
this.persistSeenIDs();
},
persistSeenIDs: function() {
if (this.seenPageIDs.size === 0) {
Services.prefs.clearUserPref(PREF_SEENPAGEIDS);
return;
}
Services.prefs.setCharPref(PREF_SEENPAGEIDS,
JSON.stringify([...this.seenPageIDs]));
},
onPageEvent: function(aEvent) {
let contentDocument = null;
if (aEvent.target instanceof Ci.nsIDOMHTMLDocument)
@ -161,11 +226,15 @@ this.UITour = {
switch (action) {
case "registerPageID": {
// This is only relevant if Telemtry is enabled.
if (!UITelemetry.enabled)
break;
// We don't want to allow BrowserUITelemetry.BUCKET_SEPARATOR in the
// pageID, as it could make parsing the telemetry bucket name difficult.
if (typeof data.pageID == "string" &&
!data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
this.seenPageIDs.add(data.pageID);
this.addSeenPageID(data.pageID);
// Store tabs and windows separately so we don't need to loop over all
// tabs when a window is closed.
@ -444,7 +513,7 @@ this.UITour = {
getTelemetry: function() {
return {
seenPageIDs: [...this.seenPageIDs],
seenPageIDs: [...this.seenPageIDs.keys()],
};
},

Просмотреть файл

@ -8,23 +8,68 @@ let gContentAPI;
let gContentWindow;
Components.utils.import("resource:///modules/UITour.jsm");
Components.utils.import("resource://gre/modules/UITelemetry.jsm");
Components.utils.import("resource:///modules/BrowserUITelemetry.jsm");
function test() {
UITelemetry._enabled = true;
registerCleanupFunction(function() {
UITour.seenPageIDs.clear();
Services.prefs.clearUserPref("browser.uitour.seenPageIDs");
resetSeenPageIDsLazyGetter();
UITelemetry._enabled = undefined;
BrowserUITelemetry.setBucket(null);
delete window.UITelemetry;
delete window.BrowserUITelemetry;
});
UITourTest();
}
function resetSeenPageIDsLazyGetter() {
delete UITour.seenPageIDs;
// This should be kept in sync with how UITour.init() sets this.
Object.defineProperty(UITour, "seenPageIDs", {
get: UITour.restoreSeenPageIDs.bind(UITour),
configurable: true,
});
}
function checkExpectedSeenPageIDs(expected) {
is(UITour.seenPageIDs.size, expected.length, "Should be " + expected.length + " total seen page IDs");
for (let id of expected)
ok(UITour.seenPageIDs.has(id), "Should have seen '" + id + "' page ID");
let prefData = Services.prefs.getCharPref("browser.uitour.seenPageIDs");
prefData = new Map(JSON.parse(prefData));
is(prefData.size, expected.length, "Should be " + expected.length + " total seen page IDs persisted");
for (let id of expected)
ok(prefData.has(id), "Should have seen '" + id + "' page ID persisted");
}
let tests = [
function test_seenPageIDs_1(done) {
function test_seenPageIDs_restore(done) {
info("Setting up seenPageIDs to be restored from pref");
let data = JSON.stringify([
["savedID1", { lastSeen: Date.now() }],
["savedID2", { lastSeen: Date.now() }],
// 3 weeks ago, should auto expire.
["savedID3", { lastSeen: Date.now() - 3 * 7 * 24 * 60 * 60 * 1000 }],
]);
Services.prefs.setCharPref("browser.uitour.seenPageIDs",
data);
resetSeenPageIDsLazyGetter();
checkExpectedSeenPageIDs(["savedID1", "savedID2"]);
done();
},
function test_seenPageIDs_set_1(done) {
gContentAPI.registerPageID("testpage1");
is(UITour.seenPageIDs.size, 1, "Should be 1 seen page ID");
ok(UITour.seenPageIDs.has("testpage1"), "Should have seen 'testpage1' page ID");
checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1"]);
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
@ -42,12 +87,10 @@ let tests = [
BrowserUITelemetry.setBucket(null);
done();
},
function test_seenPageIDs_2(done) {
function test_seenPageIDs_set_2(done) {
gContentAPI.registerPageID("testpage2");
is(UITour.seenPageIDs.size, 2, "Should be 2 seen page IDs");
ok(UITour.seenPageIDs.has("testpage1"), "Should have seen 'testpage1' page ID");
ok(UITour.seenPageIDs.has("testpage2"), "Should have seen 'testpage2' page ID");
checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1", "testpage2"]);
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;

Просмотреть файл

@ -481,7 +481,7 @@ include $(topsrcdir)/config/static-checking-config.mk
CFLAGS = $(OS_CPPFLAGS) $(OS_CFLAGS)
CXXFLAGS = $(OS_CPPFLAGS) $(OS_CXXFLAGS)
LDFLAGS = $(OS_LDFLAGS) $(MOZ_FIX_LINK_PATHS)
LDFLAGS = $(OS_LDFLAGS) $(MOZBUILD_LDFLAGS) $(MOZ_FIX_LINK_PATHS)
# Allow each module to override the *default* optimization settings
# by setting MODULE_OPTIMIZE_FLAGS if the developer has not given
@ -587,10 +587,10 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
endif
endif
COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS) $(EXTRA_COMPILE_FLAGS)
ASFLAGS += $(EXTRA_ASSEMBLER_FLAGS)
ifndef CROSS_COMPILE

Просмотреть файл

@ -1299,16 +1299,6 @@ if test "$GNU_CC"; then
CFLAGS="$CFLAGS -fno-strict-aliasing"
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
DSO_LDOPTS='-shared'
if test "$GCC_USE_GNU_LD"; then
# Some tools like ASan use a runtime library that is only
# linked against executables, so we must allow undefined
# symbols for shared objects in some cases.
if test -z "$MOZ_NO_WLZDEFS"; then
# Don't allow undefined symbols in libraries
DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
fi
fi
WARNINGS_AS_ERRORS='-Werror'
DSO_CFLAGS=''
DSO_PIC_CFLAGS='-fPIC'
@ -1343,6 +1333,14 @@ if test "$GNU_CC"; then
AC_MSG_RESULT([no])
LDFLAGS=$_SAVE_LDFLAGS)
AC_MSG_CHECKING([for --ignore-unresolved-symbol option to ld])
HAVE_LINKER_SUPPORT_IGNORE_UNRESOLVED=
_SAVE_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--ignore-unresolved-symbol,environ"
AC_TRY_LINK(,,AC_MSG_RESULT([yes])
[HAVE_LINKER_SUPPORT_IGNORE_UNRESOLVED=1],
AC_MSG_RESULT([no]))
LDFLAGS=$_SAVE_LDFLAGS
# Check for -mssse3 on $CC
AC_MSG_CHECKING([if toolchain supports -mssse3 option])
@ -1378,6 +1376,28 @@ if test "$GNU_CC"; then
fi
esac
DSO_LDOPTS='-shared'
if test "$GCC_USE_GNU_LD"; then
# Some tools like ASan use a runtime library that is only
# linked against executables, so we must allow undefined
# symbols for shared objects in some cases.
if test -z "$MOZ_NO_WLZDEFS"; then
# Don't allow undefined symbols in libraries
DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
# BSDs need `environ' exposed for posix_spawn (bug 753046)
case "$OS_TARGET" in
DragonFly|FreeBSD|NetBSD|OpenBSD)
if test -n "$HAVE_LINKER_SUPPORT_IGNORE_UNRESOLVED"; then
DSO_LDOPTS="$DSO_LDOPTS -Wl,--ignore-unresolved-symbol,environ"
else
DSO_LDOPTS="$DSO_LDOPTS -Wl,--warn-unresolved-symbols"
fi
;;
esac
fi
fi
# Turn on GNU-specific warnings:
# -Wall - turn on a lot of warnings
# -Wpointer-arith - good to have
@ -6270,6 +6290,14 @@ if test -n "$MOZ_DISABLE_CRYPTOLEGACY"; then
fi
AC_SUBST(MOZ_DISABLE_CRYPTOLEGACY)
dnl ========================================================
dnl = Disable EV certificate verification
dnl ========================================================
if test -n "$MOZ_NO_EV_CERTS"; then
AC_DEFINE(MOZ_NO_EV_CERTS)
fi
AC_SUBST(MOZ_NO_EV_CERTS)
dnl ========================================================
dnl = Disable libpkix
dnl ========================================================

Просмотреть файл

@ -1643,20 +1643,31 @@ public:
// owning Documents needs it to animate; otherwise it can suspend.
virtual void SetImagesNeedAnimating(bool aAnimating) = 0;
enum SuppressionType {
eAnimationsOnly = 0x1,
// Note that suppressing events also suppresses animation frames, so
// there's no need to split out events in its own bitmask.
eEvents = 0x3,
};
/**
* Prevents user initiated events from being dispatched to the document and
* subdocuments.
*/
virtual void SuppressEventHandling(uint32_t aIncrease = 1) = 0;
virtual void SuppressEventHandling(SuppressionType aWhat,
uint32_t aIncrease = 1) = 0;
/**
* Unsuppress event handling.
* @param aFireEvents If true, delayed events (focus/blur) will be fired
* asynchronously.
*/
virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) = 0;
virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
bool aFireEvents) = 0;
uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; }
uint32_t AnimationsPaused() const { return mAnimationsPaused; }
bool IsEventHandlingEnabled() {
return !EventHandlingSuppressed() && mScriptGlobalObject;
@ -2487,6 +2498,8 @@ protected:
uint32_t mEventsSuppressed;
uint32_t mAnimationsPaused;
/**
* The number number of external scripts (ones with the src attribute) that
* have this document as their owner and that are being evaluated right now.

Просмотреть файл

@ -49,13 +49,13 @@
#include "nsIMIMEService.h"
#include "imgIContainer.h"
#include "imgIRequest.h"
#include "nsDOMDataTransfer.h"
#include "mozilla/dom/DataTransfer.h"
#include "nsIMIMEInfo.h"
#include "nsRange.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLAreaElement.h"
using mozilla::dom::HTMLAreaElement;
using namespace mozilla::dom;
class MOZ_STACK_CLASS DragDataProducer
{
@ -64,18 +64,18 @@ public:
nsIContent* aTarget,
nsIContent* aSelectionTargetNode,
bool aIsAltKeyPressed);
nsresult Produce(nsDOMDataTransfer* aDataTransfer,
nsresult Produce(DataTransfer* aDataTransfer,
bool* aCanDrag,
nsISelection** aSelection,
nsIContent** aDragNode);
private:
void AddString(nsDOMDataTransfer* aDataTransfer,
void AddString(DataTransfer* aDataTransfer,
const nsAString& aFlavor,
const nsAString& aData,
nsIPrincipal* aPrincipal);
nsresult AddStringsToDataTransfer(nsIContent* aDragNode,
nsDOMDataTransfer* aDataTransfer);
DataTransfer* aDataTransfer);
static nsresult GetDraggableSelectionData(nsISelection* inSelection,
nsIContent* inRealTargetNode,
nsIContent **outImageOrLinkNode,
@ -112,7 +112,7 @@ nsContentAreaDragDrop::GetDragData(nsPIDOMWindow* aWindow,
nsIContent* aTarget,
nsIContent* aSelectionTargetNode,
bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer,
DataTransfer* aDataTransfer,
bool* aCanDrag,
nsISelection** aSelection,
nsIContent** aDragNode)
@ -354,7 +354,7 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
}
nsresult
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
DragDataProducer::Produce(DataTransfer* aDataTransfer,
bool* aCanDrag,
nsISelection** aSelection,
nsIContent** aDragNode)
@ -703,7 +703,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
}
void
DragDataProducer::AddString(nsDOMDataTransfer* aDataTransfer,
DragDataProducer::AddString(DataTransfer* aDataTransfer,
const nsAString& aFlavor,
const nsAString& aData,
nsIPrincipal* aPrincipal)
@ -717,7 +717,7 @@ DragDataProducer::AddString(nsDOMDataTransfer* aDataTransfer,
nsresult
DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
nsDOMDataTransfer* aDataTransfer)
DataTransfer* aDataTransfer)
{
NS_ASSERTION(aDragNode, "adding strings for null node");

Просмотреть файл

@ -21,7 +21,12 @@ class nsIContent;
class nsIURI;
class nsIFile;
class nsISimpleEnumerator;
class nsDOMDataTransfer;
namespace mozilla {
namespace dom {
class DataTransfer;
}
}
//
// class nsContentAreaDragDrop, used to generate the dragdata
@ -52,7 +57,7 @@ public:
nsIContent* aTarget,
nsIContent* aSelectionTargetNode,
bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer,
mozilla::dom::DataTransfer* aDataTransfer,
bool* aCanDrag,
nsISelection** aSelection,
nsIContent** aDragNode);

Просмотреть файл

@ -67,7 +67,7 @@
#include "nsDocShellCID.h"
#include "nsDocument.h"
#include "nsDOMCID.h"
#include "nsDOMDataTransfer.h"
#include "mozilla/dom/DataTransfer.h"
#include "nsDOMJSUtils.h"
#include "nsDOMMutationObserver.h"
#include "nsDOMTouchEvent.h"
@ -4974,16 +4974,20 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
if (!initialDataTransfer) {
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
nsCOMPtr<DataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
if (dataTransfer) {
initialDataTransfer = do_QueryInterface(dataTransfer);
if (!initialDataTransfer) {
return NS_ERROR_FAILURE;
}
} else {
// A dataTransfer won't exist when a drag was started by some other
// means, for instance calling the drag service directly, or a drag
// from another application. In either case, a new dataTransfer should
// be created that reflects the data.
initialDataTransfer = new nsDOMDataTransfer(aDragEvent->message, true, -1);
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
initialDataTransfer = new DataTransfer(aDragEvent->target, aDragEvent->message, true, -1);
// now set it in the drag session so we don't need to create it again
dragSession->SetDataTransfer(initialDataTransfer);
@ -4996,7 +5000,7 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
}
// each event should use a clone of the original dataTransfer.
initialDataTransfer->Clone(aDragEvent->message, aDragEvent->userCancelled,
initialDataTransfer->Clone(aDragEvent->target, aDragEvent->message, aDragEvent->userCancelled,
isCrossDomainSubFrameDrop,
getter_AddRefs(aDragEvent->dataTransfer));
NS_ENSURE_TRUE(aDragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);

Просмотреть файл

@ -20,7 +20,7 @@
#include "nsIPresShell.h"
#include "nsFocusManager.h"
#include "nsEventDispatcher.h"
#include "nsDOMDataTransfer.h"
#include "mozilla/dom/DataTransfer.h"
#include "nsIDocShell.h"
#include "nsIContentViewerEdit.h"
@ -53,6 +53,7 @@
#include "mozilla/Preferences.h"
using namespace mozilla;
using namespace mozilla::dom;
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
@ -643,9 +644,10 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
// next, fire the cut, copy or paste event
bool doDefault = true;
nsRefPtr<nsDOMDataTransfer> clipboardData;
nsRefPtr<DataTransfer> clipboardData;
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
clipboardData = new nsDOMDataTransfer(aType, aType == NS_PASTE, aClipboardType);
clipboardData =
new DataTransfer(piWindow, aType, aType == NS_PASTE, aClipboardType);
nsEventStatus status = nsEventStatus_eIgnore;
InternalClipboardEvent evt(true, aType);

Просмотреть файл

@ -9145,22 +9145,41 @@ nsIDocument::GetReadyState(nsAString& aReadyState) const
}
}
namespace {
struct SuppressArgs
{
nsIDocument::SuppressionType mWhat;
uint32_t mIncrease;
};
}
static bool
SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
{
aDocument->SuppressEventHandling(*static_cast<uint32_t*>(aData));
SuppressArgs* args = static_cast<SuppressArgs*>(aData);
aDocument->SuppressEventHandling(args->mWhat, args->mIncrease);
return true;
}
void
nsDocument::SuppressEventHandling(uint32_t aIncrease)
nsDocument::SuppressEventHandling(nsIDocument::SuppressionType aWhat,
uint32_t aIncrease)
{
if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
mScriptGlobalObject) {
if (mEventsSuppressed == 0 && mAnimationsPaused == 0 &&
aIncrease != 0 && mPresShell && mScriptGlobalObject) {
RevokeAnimationFrameNotifications();
}
mEventsSuppressed += aIncrease;
EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
if (aWhat == eAnimationsOnly) {
mAnimationsPaused += aIncrease;
} else {
mEventsSuppressed += aIncrease;
}
SuppressArgs args = { aWhat, aIncrease };
EnumerateSubDocuments(SuppressEventHandlingInDocument, &args);
}
static void
@ -9314,30 +9333,59 @@ private:
nsTArray<nsCOMPtr<nsIDocument> > mDocuments;
};
static bool
GetAndUnsuppressSubDocuments(nsIDocument* aDocument, void* aData)
namespace {
struct UnsuppressArgs
{
uint32_t suppression = aDocument->EventHandlingSuppressed();
if (suppression > 0) {
static_cast<nsDocument*>(aDocument)->DecreaseEventSuppression();
UnsuppressArgs(nsIDocument::SuppressionType aWhat)
: mWhat(aWhat)
{
}
nsTArray<nsCOMPtr<nsIDocument> >* docs =
static_cast<nsTArray<nsCOMPtr<nsIDocument> >* >(aData);
docs->AppendElement(aDocument);
aDocument->EnumerateSubDocuments(GetAndUnsuppressSubDocuments, docs);
nsIDocument::SuppressionType mWhat;
nsTArray<nsCOMPtr<nsIDocument>> mDocs;
};
}
static bool
GetAndUnsuppressSubDocuments(nsIDocument* aDocument,
void* aData)
{
UnsuppressArgs* args = static_cast<UnsuppressArgs*>(aData);
if (args->mWhat != nsIDocument::eAnimationsOnly &&
aDocument->EventHandlingSuppressed() > 0) {
static_cast<nsDocument*>(aDocument)->DecreaseEventSuppression();
} else if (args->mWhat == nsIDocument::eAnimationsOnly &&
aDocument->AnimationsPaused()) {
static_cast<nsDocument*>(aDocument)->ResumeAnimations();
}
if (args->mWhat != nsIDocument::eAnimationsOnly) {
// No need to remember documents if we only care about animation frames.
args->mDocs.AppendElement(aDocument);
}
aDocument->EnumerateSubDocuments(GetAndUnsuppressSubDocuments, aData);
return true;
}
void
nsDocument::UnsuppressEventHandlingAndFireEvents(bool aFireEvents)
nsDocument::UnsuppressEventHandlingAndFireEvents(nsIDocument::SuppressionType aWhat,
bool aFireEvents)
{
nsTArray<nsCOMPtr<nsIDocument> > documents;
GetAndUnsuppressSubDocuments(this, &documents);
UnsuppressArgs args(aWhat);
GetAndUnsuppressSubDocuments(this, &args);
if (aWhat == nsIDocument::eAnimationsOnly) {
// No need to fire events if we only care about animations here.
return;
}
if (aFireEvents) {
NS_DispatchToCurrentThread(new nsDelayedEventDispatcher(documents));
NS_DispatchToCurrentThread(new nsDelayedEventDispatcher(args.mDocs));
} else {
FireOrClearDelayedEvents(documents, false);
FireOrClearDelayedEvents(args.mDocs, false);
}
}

Просмотреть файл

@ -980,15 +980,24 @@ public:
void SetImagesNeedAnimating(bool aAnimating) MOZ_OVERRIDE;
virtual void SuppressEventHandling(uint32_t aIncrease) MOZ_OVERRIDE;
virtual void SuppressEventHandling(SuppressionType aWhat,
uint32_t aIncrease) MOZ_OVERRIDE;
virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
bool aFireEvents) MOZ_OVERRIDE;
virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) MOZ_OVERRIDE;
void DecreaseEventSuppression() {
MOZ_ASSERT(mEventsSuppressed);
--mEventsSuppressed;
MaybeRescheduleAnimationFrameNotifications();
}
void ResumeAnimations() {
MOZ_ASSERT(mAnimationsPaused);
--mAnimationsPaused;
MaybeRescheduleAnimationFrameNotifications();
}
virtual nsIDocument* GetTemplateContentsOwner() MOZ_OVERRIDE;
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,

Просмотреть файл

@ -1821,6 +1821,7 @@ GK_ATOM(flexContainerFrame, "FlexContainerFrame")
GK_ATOM(formControlFrame, "FormControlFrame") // radio or checkbox
GK_ATOM(frameSetFrame, "FrameSetFrame")
GK_ATOM(gfxButtonControlFrame, "gfxButtonControlFrame")
GK_ATOM(gridContainerFrame, "GridContainerFrame")
GK_ATOM(HTMLButtonControlFrame, "HTMLButtonControlFrame")
GK_ATOM(HTMLCanvasFrame, "HTMLCanvasFrame")
GK_ATOM(subDocumentFrame, "subDocumentFrame")

Просмотреть файл

@ -16,7 +16,7 @@
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsTraceRefcnt.h"
#include "nsISupportsImpl.h"
class nsString;
class nsCString;

Просмотреть файл

@ -2872,7 +2872,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
(suspendedWindow = suspendedWindow->GetCurrentInnerWindow())) {
suspendedDoc = suspendedWindow->GetExtantDoc();
if (suspendedDoc) {
suspendedDoc->SuppressEventHandling();
suspendedDoc->SuppressEventHandling(nsIDocument::eEvents);
}
suspendedWindow->SuspendTimeouts(1, false);
resumeTimeoutRunnable = new nsResumeTimeoutsEvent(suspendedWindow);
@ -2896,7 +2896,8 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
}
if (suspendedDoc) {
suspendedDoc->UnsuppressEventHandlingAndFireEvents(true);
suspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
true);
}
if (resumeTimeoutRunnable) {

Просмотреть файл

@ -15,7 +15,7 @@
#include <stdint.h>
#include "nsCycleCollectionParticipant.h"
#include "nsTraceRefcnt.h"
#include "nsISupportsImpl.h"
#include "js/GCAPI.h"
namespace mozilla {

Просмотреть файл

@ -3342,6 +3342,12 @@ WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
return;
}
if (!ValidateCompTexImageSize(target, level, internalformat, 0, 0,
width, height, width, height, func))
{
return;
}
MakeContextCurrent();
gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
WebGLTexture* tex = activeBoundTextureForTarget(target);
@ -3376,6 +3382,10 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
MOZ_ASSERT(tex);
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(target, level);
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, format, width, height, byteLength, func))
return;
if (!ValidateCompTexImageSize(target, level, format,
xoffset, yoffset,
width, height,
@ -3385,10 +3395,6 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
return;
}
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, format, width, height, byteLength, func))
return;
if (levelInfo.HasUninitializedImageData())
tex->DoDeferredImageInitialization(target, level);

Просмотреть файл

@ -776,26 +776,54 @@ WebGLContext::ValidateCompTexImageSize(GLenum target, GLint level, GLenum format
/* The size must be a multiple of blockWidth and blockHeight,
* or must be using offset+size that exactly hits the edge.
* Important for small mipmap levels. (s3tc extension appears
* to have changed and old code that checks 1x1, 2x2 doesn't
* appear necessary anymore)
* Important for small mipmap levels.
*/
if ((width % blockWidth != 0) &&
(xoffset + width != (GLint) levelWidth))
{
ErrorInvalidOperation("%s: width must be multiple of %d or "
"xoffset + width must be %d",
InfoFrom(func), blockWidth, levelWidth);
return false;
/* https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
* "When level equals zero width and height must be a multiple of 4. When
* level is greater than 0 width and height must be 0, 1, 2 or a multiple of 4.
* If they are not an INVALID_OPERATION error is generated."
*/
if (level == 0) {
if (width % blockWidth != 0) {
ErrorInvalidOperation("%s: width of level 0 must be multple of %d",
InfoFrom(func), blockWidth);
return false;
}
if (height % blockHeight != 0) {
ErrorInvalidOperation("%s: height of level 0 must be multipel of %d",
InfoFrom(func), blockHeight);
return false;
}
}
else if (level > 0) {
if (width % blockWidth != 0 && width > 2) {
ErrorInvalidOperation("%s: width of level %d must be multiple"
" of %d or 0, 1, 2",
InfoFrom(func), level, blockWidth);
return false;
}
if (height % blockHeight != 0 && height > 2) {
ErrorInvalidOperation("%s: height of level %d must be multiple"
" of %d or 0, 1, 2",
InfoFrom(func), level, blockHeight);
return false;
}
}
if ((height % blockHeight != 0) &&
(yoffset + height != (GLint) levelHeight))
{
ErrorInvalidOperation("%s: height must be multiple of %d or "
"yoffset + height must be %d",
InfoFrom(func), blockHeight, levelHeight);
return false;
if (IsSubFunc(func)) {
if ((xoffset % blockWidth) != 0) {
ErrorInvalidOperation("%s: xoffset must be multiple of %d",
InfoFrom(func), blockWidth);
return false;
}
if (yoffset % blockHeight != 0) {
ErrorInvalidOperation("%s: yoffset must be multiple of %d",
InfoFrom(func), blockHeight);
return false;
}
}
}
@ -1153,10 +1181,26 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTex
validCombo = (type == LOCAL_GL_UNSIGNED_INT_24_8);
break;
case LOCAL_GL_ATC_RGB:
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE);
break;
default:
// Only valid formats should be passed to the switch stmt.
MOZ_ASSERT("Invalid format");
return false;
MOZ_ASSERT(false, "Unexpected format and type combo. How'd this happen?");
validCombo = false;
// Fall through to return an InvalidOperations. This will alert us to the
// unexpected case that needs fixing in builds without asserts.
}
if (!validCombo)

Просмотреть файл

@ -515,12 +515,11 @@ AudioNodeStream::FinishOutput()
}
}
TrackTicks
AudioNodeStream::TicksFromDestinationTime(MediaStream* aDestination,
double aSeconds)
double
AudioNodeStream::TimeFromDestinationTime(AudioNodeStream* aDestination,
double aSeconds)
{
MOZ_ASSERT(aDestination->AsAudioNodeStream() &&
aDestination->AsAudioNodeStream()->SampleRate() == SampleRate());
MOZ_ASSERT(aDestination->SampleRate() == SampleRate());
double destinationSeconds = std::max(0.0, aSeconds);
StreamTime streamTime = SecondsToMediaTime(destinationSeconds);
@ -531,6 +530,17 @@ AudioNodeStream::TicksFromDestinationTime(MediaStream* aDestination,
StreamTime thisStreamTime = GraphTimeToStreamTimeOptimistic(graphTime);
double thisSeconds = MediaTimeToSeconds(thisStreamTime) + offset;
MOZ_ASSERT(thisSeconds >= 0.0);
return thisSeconds;
}
TrackTicks
AudioNodeStream::TicksFromDestinationTime(MediaStream* aDestination,
double aSeconds)
{
AudioNodeStream* destination = aDestination->AsAudioNodeStream();
MOZ_ASSERT(destination);
double thisSeconds = TimeFromDestinationTime(destination, aSeconds);
// Round to nearest
TrackTicks ticks = thisSeconds * SampleRate() + 0.5;
return ticks;

Просмотреть файл

@ -128,6 +128,12 @@ public:
AudioNodeEngine* Engine() { return mEngine; }
TrackRate SampleRate() const { return mSampleRate; }
/**
* Convert a time in seconds on the destination stream to seconds
* on this stream.
*/
double TimeFromDestinationTime(AudioNodeStream* aDestination,
double aSeconds);
/**
* Convert a time in seconds on the destination stream to TrackTicks
* on this stream.

Просмотреть файл

@ -10,7 +10,7 @@
#include <algorithm>
#include "nsISeekableStream.h"
#include "nsTraceRefcnt.h"
#include "nsISupportsImpl.h"
#include "prenv.h"
#include "prlog.h"

Просмотреть файл

@ -1,4 +1,4 @@
[DEFAULT]
support-files = seek.webm
support-files = seek.webm seek.webm^headers^
[test_MediaSource.html]

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -14,7 +14,7 @@
#include "MediaDecoderReader.h"
#include "OggCodecState.h"
#include "OggDecoder.h"
#include "nsTraceRefcnt.h"
#include "nsISupportsImpl.h"
#include "VideoUtils.h"
#include <algorithm>

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -1,2 +1,2 @@
X-Content-Duration: 1.96
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -1,2 +1,2 @@
X-Content-Duration: 9000
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше