зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to central, a=merge
MozReview-Commit-ID: AFEWjI3UWey
This commit is contained in:
Коммит
0af59511ea
|
@ -6,6 +6,7 @@ module.exports = {
|
|||
],
|
||||
|
||||
"rules": {
|
||||
"no-shadow": "error"
|
||||
"no-shadow": "error",
|
||||
"no-undef": "off"
|
||||
}
|
||||
};
|
||||
|
|
|
@ -351,6 +351,9 @@
|
|||
function initPageCertError() {
|
||||
document.body.className = "certerror";
|
||||
document.title = document.getElementById("certErrorPageTitle").textContent;
|
||||
for (let host of document.querySelectorAll(".hostname")) {
|
||||
host.textContent = document.location.hostname;
|
||||
}
|
||||
|
||||
setupAdvancedButton(true);
|
||||
|
||||
|
|
|
@ -175,7 +175,9 @@ var StarUI = {
|
|||
}
|
||||
clearTimeout(this._autoCloseTimer);
|
||||
this._autoCloseTimer = setTimeout(() => {
|
||||
this.panel.hidePopup();
|
||||
if (!this.panel.mozMatchesSelector(":hover")) {
|
||||
this.panel.hidePopup();
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -217,7 +217,7 @@ add_task(function* checkWrongSystemTimeWarning() {
|
|||
});
|
||||
|
||||
add_task(function* checkAdvancedDetails() {
|
||||
info("Loading a bad cert page and verifying the advanced details section");
|
||||
info("Loading a bad cert page and verifying the main error and advanced details section");
|
||||
let browser;
|
||||
let certErrorLoaded;
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
|
||||
|
@ -231,6 +231,11 @@ add_task(function* checkAdvancedDetails() {
|
|||
|
||||
let message = yield ContentTask.spawn(browser, null, function* () {
|
||||
let doc = content.document;
|
||||
let shortDescText = doc.getElementById("errorShortDescText");
|
||||
info("Main error text: " + shortDescText.textContent);
|
||||
ok(shortDescText.textContent.includes("expired.example.com"),
|
||||
"Should list hostname in error message.");
|
||||
|
||||
let advancedButton = doc.getElementById("advancedButton");
|
||||
advancedButton.click();
|
||||
let el = doc.getElementById("errorCode");
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
let bookmarkPanel = document.getElementById("editBookmarkPanel");
|
||||
let bookmarkStar = document.getElementById("bookmarks-menu-button");
|
||||
let bookmarkPanelTitle = document.getElementById("editBookmarkPanelTitle");
|
||||
let editBookmarkPanelRemoveButtonRect;
|
||||
|
||||
StarUI._closePanelQuickForTesting = true;
|
||||
|
||||
|
@ -34,6 +35,9 @@ function* test_bookmarks_popup({isNewBookmark, popupShowFn, popupEditFn,
|
|||
yield shownPromise;
|
||||
is(bookmarkPanel.state, "open", "Panel should be 'open' after shownPromise is resolved");
|
||||
|
||||
editBookmarkPanelRemoveButtonRect =
|
||||
document.getElementById("editBookmarkPanelRemoveButton").getBoundingClientRect();
|
||||
|
||||
if (popupEditFn) {
|
||||
yield popupEditFn();
|
||||
}
|
||||
|
@ -363,6 +367,32 @@ add_task(function* enter_on_remove_bookmark_should_remove_bookmark() {
|
|||
});
|
||||
});
|
||||
|
||||
add_task(function* mouse_hovering_panel_should_prevent_autoclose() {
|
||||
if (AppConstants.platform != "win") {
|
||||
// This test requires synthesizing native mouse movement which is
|
||||
// best supported on Windows.
|
||||
return;
|
||||
}
|
||||
yield test_bookmarks_popup({
|
||||
isNewBookmark: true,
|
||||
*popupShowFn(browser) {
|
||||
yield new Promise(resolve => {
|
||||
EventUtils.synthesizeNativeMouseMove(
|
||||
document.documentElement,
|
||||
editBookmarkPanelRemoveButtonRect.left,
|
||||
editBookmarkPanelRemoveButtonRect.top,
|
||||
resolve);
|
||||
});
|
||||
EventUtils.synthesizeKey("D", {accelKey: true}, window);
|
||||
},
|
||||
shouldAutoClose: false,
|
||||
popupHideFn() {
|
||||
document.getElementById("editBookmarkPanelRemoveButton").click();
|
||||
},
|
||||
isBookmarkRemoved: true,
|
||||
});
|
||||
});
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
delete StarUI._closePanelQuickForTesting;
|
||||
})
|
||||
|
|
|
@ -48,6 +48,14 @@ let whitelist = [
|
|||
isFromDevTools: false},
|
||||
];
|
||||
|
||||
if (!Services.prefs.getBoolPref("full-screen-api.unprefix.enabled")) {
|
||||
whitelist.push({
|
||||
sourceName: /res\/(ua|html)\.css$/i,
|
||||
errorMessage: /Unknown pseudo-class .*\bfullscreen\b/i,
|
||||
isFromDevTools: false
|
||||
});
|
||||
}
|
||||
|
||||
// Platform can be "linux", "macosx" or "win". If omitted, the exception applies to all platforms.
|
||||
let allowedImageReferences = [
|
||||
// Bug 1302691
|
||||
|
|
|
@ -3,5 +3,4 @@ support-files =
|
|||
head.js
|
||||
|
||||
[browser_identityBlock_focus.js]
|
||||
skip-if = os == 'mac' # Bug 1334418 (try only)
|
||||
support-files = ../general/permissions.html
|
||||
|
|
|
@ -14,6 +14,7 @@ function synthesizeKeyAndWaitForFocus(element, keyCode, options) {
|
|||
// Checks that the identity block is the next element after the urlbar
|
||||
// to be focused if there are no active notification anchors.
|
||||
add_task(function* testWithoutNotifications() {
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
|
||||
yield BrowserTestUtils.withNewTab("https://example.com", function*() {
|
||||
yield synthesizeKeyAndWaitForFocus(gURLBar, "l", {accelKey: true})
|
||||
is(document.activeElement, gURLBar.inputField, "urlbar should be focused");
|
||||
|
@ -26,7 +27,7 @@ add_task(function* testWithoutNotifications() {
|
|||
// Checks that when there is a notification anchor, it will receive
|
||||
// focus before the identity block.
|
||||
add_task(function* testWithoutNotifications() {
|
||||
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
|
||||
yield BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, function*(browser) {
|
||||
let popupshown = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
|
||||
// Request a permission;
|
||||
|
@ -46,6 +47,7 @@ add_task(function* testWithoutNotifications() {
|
|||
|
||||
// Checks that with invalid pageproxystate the identity block is ignored.
|
||||
add_task(function* testInvalidPageProxyState() {
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
|
||||
yield BrowserTestUtils.withNewTab("about:blank", function*(browser) {
|
||||
// Loading about:blank will automatically focus the urlbar, which, however, can
|
||||
// race with the test code. So we only send the shortcut if the urlbar isn't focused yet.
|
||||
|
|
|
@ -2124,7 +2124,7 @@
|
|||
|
||||
<handler event="mousedown"><![CDATA[
|
||||
let target = event.originalTarget;
|
||||
if (!target.classList.contains("searchbar-engine-one-off-item")) {
|
||||
if (target.getAttribute("anonid") == "addengine-menu-button") {
|
||||
return;
|
||||
}
|
||||
// Required to receive click events from the buttons on Linux.
|
||||
|
|
|
@ -343,6 +343,7 @@ this.ExtensionsUI = {
|
|||
|
||||
let options = {
|
||||
hideClose: true,
|
||||
timeout: Date.now() + 30000,
|
||||
popupIconURL: addon.iconURL || DEFAULT_EXTENSION_ICON,
|
||||
eventCallback(topic) {
|
||||
if (topic == "showing") {
|
||||
|
|
|
@ -14,6 +14,8 @@ const {gDevTools} = require("devtools/client/framework/devtools");
|
|||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
|
||||
|
||||
loader.lazyRequireGetter(this, "system", "devtools/shared/system");
|
||||
|
||||
exports.OptionsPanel = OptionsPanel;
|
||||
|
||||
function GetPref(name) {
|
||||
|
@ -91,6 +93,7 @@ OptionsPanel.prototype = {
|
|||
this.setupToolsList();
|
||||
this.setupToolbarButtonsList();
|
||||
this.setupThemeList();
|
||||
this.setupNightlyOptions();
|
||||
yield this.populatePreferences();
|
||||
this.isReady = true;
|
||||
this.emit("ready");
|
||||
|
@ -302,6 +305,55 @@ OptionsPanel.prototype = {
|
|||
this.updateCurrentTheme();
|
||||
},
|
||||
|
||||
/**
|
||||
* Add common preferences enabled only on Nightly.
|
||||
*/
|
||||
setupNightlyOptions: function () {
|
||||
let isNightly = system.constants.NIGHTLY_BUILD;
|
||||
if (!isNightly) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Labels for these new buttons are nightly only and mostly intended for working on
|
||||
// devtools. They should not be localized.
|
||||
let prefDefinitions = [{
|
||||
pref: "devtools.webconsole.new-frontend-enabled",
|
||||
label: "Enable new console frontend",
|
||||
id: "devtools-new-webconsole",
|
||||
parentId: "webconsole-options"
|
||||
}, {
|
||||
pref: "devtools.debugger.new-debugger-frontend",
|
||||
label: "Enable new debugger frontend",
|
||||
id: "devtools-new-debugger",
|
||||
parentId: "debugger-options"
|
||||
}];
|
||||
|
||||
let createPreferenceOption = ({pref, label, id}) => {
|
||||
let inputLabel = this.panelDoc.createElement("label");
|
||||
let checkbox = this.panelDoc.createElement("input");
|
||||
checkbox.setAttribute("type", "checkbox");
|
||||
if (GetPref(pref)) {
|
||||
checkbox.setAttribute("checked", "checked");
|
||||
}
|
||||
checkbox.setAttribute("id", id);
|
||||
checkbox.addEventListener("change", e => {
|
||||
SetPref(pref, e.target.checked);
|
||||
});
|
||||
|
||||
let inputSpanLabel = this.panelDoc.createElement("span");
|
||||
inputSpanLabel.textContent = label;
|
||||
inputLabel.appendChild(checkbox);
|
||||
inputLabel.appendChild(inputSpanLabel);
|
||||
|
||||
return inputLabel;
|
||||
};
|
||||
|
||||
for (let prefDefinition of prefDefinitions) {
|
||||
let parent = this.panelDoc.getElementById(prefDefinition.parentId);
|
||||
parent.appendChild(createPreferenceOption(prefDefinition));
|
||||
}
|
||||
},
|
||||
|
||||
populatePreferences: function () {
|
||||
let prefCheckboxes = this.panelDoc.querySelectorAll(
|
||||
"input[type=checkbox][data-pref]");
|
||||
|
|
|
@ -2023,6 +2023,12 @@ Element::GetInlineStyleDeclaration() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const nsMappedAttributes*
|
||||
Element::GetMappedAttributes() const
|
||||
{
|
||||
return mAttrsAndChildren.GetMapped();
|
||||
}
|
||||
|
||||
nsresult
|
||||
Element::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
|
|
|
@ -281,6 +281,11 @@ public:
|
|||
*/
|
||||
DeclarationBlock* GetInlineStyleDeclaration() const;
|
||||
|
||||
/**
|
||||
* Get the mapped attributes, if any, for this element.
|
||||
*/
|
||||
const nsMappedAttributes* GetMappedAttributes() const;
|
||||
|
||||
/**
|
||||
* Set the inline style declaration for this element. This will send
|
||||
* an appropriate AttributeChanged notification if aNotify is true.
|
||||
|
|
|
@ -772,6 +772,11 @@ nsAttrAndChildArray::MakeMappedUnique(nsMappedAttributes* aAttributes)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
const nsMappedAttributes*
|
||||
nsAttrAndChildArray::GetMapped() const
|
||||
{
|
||||
return mImpl ? mImpl->mMappedAttrs : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsAttrAndChildArray::GrowBy(uint32_t aGrowSize)
|
||||
|
|
|
@ -134,6 +134,7 @@ public:
|
|||
{
|
||||
return MappedAttrCount();
|
||||
}
|
||||
const nsMappedAttributes* GetMapped() const;
|
||||
|
||||
private:
|
||||
nsAttrAndChildArray(const nsAttrAndChildArray& aOther) = delete;
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include "nsMappedAttributes.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
#include "nsRuleWalker.h"
|
||||
#include "nsRuleData.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ServoDeclarationBlock.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -21,14 +23,18 @@ nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
|
|||
nsMapRuleToAttributesFunc aMapRuleFunc)
|
||||
: mAttrCount(0),
|
||||
mSheet(aSheet),
|
||||
mRuleMapper(aMapRuleFunc)
|
||||
mRuleMapper(aMapRuleFunc),
|
||||
mServoStyle(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsMappedAttributes::nsMappedAttributes(const nsMappedAttributes& aCopy)
|
||||
: mAttrCount(aCopy.mAttrCount),
|
||||
mSheet(aCopy.mSheet),
|
||||
mRuleMapper(aCopy.mRuleMapper)
|
||||
mRuleMapper(aCopy.mRuleMapper),
|
||||
// This is only called by ::Clone, which is used to create independent
|
||||
// nsMappedAttributes objects which should not share a ServoDeclarationBlock
|
||||
mServoStyle(nullptr)
|
||||
{
|
||||
NS_ASSERTION(mBufferSize >= aCopy.mAttrCount, "can't fit attributes");
|
||||
|
||||
|
@ -281,3 +287,20 @@ nsMappedAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
nsMappedAttributes::LazilyResolveServoDeclaration(nsRuleData* aRuleData,
|
||||
nsCSSPropertyID* aIndexToIdMapping,
|
||||
size_t aRuleDataSize)
|
||||
{
|
||||
MapRuleInfoInto(aRuleData);
|
||||
|
||||
MOZ_ASSERT(!mServoStyle,
|
||||
"LazilyResolveServoDeclaration should not be called if mServoStyle is already set");
|
||||
mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
|
||||
for (size_t i = 0; i < aRuleDataSize; i++) {
|
||||
nsCSSValue& val = aRuleData->mValueStorage[i];
|
||||
if (val.GetUnit() != eCSSUnit_Null) {
|
||||
Servo_DeclarationBlock_AddPresValue(mServoStyle.get(), aIndexToIdMapping[i], &val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsMappedAttributeElement.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
class nsIAtom;
|
||||
|
@ -70,9 +71,27 @@ public:
|
|||
void RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
|
||||
const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
|
||||
int32_t IndexOfAttr(nsIAtom* aLocalName) const;
|
||||
|
||||
|
||||
// nsIStyleRule
|
||||
// Apply the contained mapper to an empty nsRuleData object
|
||||
// that is able to contain all properties. Set contained servo declaration block
|
||||
// to result of this computation.
|
||||
// aIndexToIdMapping is
|
||||
// a table that maps from an index in the rule data to the corresponding
|
||||
// property ID. aRuleDataSize is the length of the backing storage
|
||||
// of the rule data.
|
||||
void LazilyResolveServoDeclaration(nsRuleData* aRuleData,
|
||||
nsCSSPropertyID* aIndexToIdMapping,
|
||||
size_t aRuleDataSize);
|
||||
|
||||
// Obtain the contained servo declaration block
|
||||
// May return null if called before the inner block
|
||||
// has been (lazily) resolved
|
||||
const RefPtr<RawServoDeclarationBlock>& GetServoStyle() const
|
||||
{
|
||||
return mServoStyle;
|
||||
}
|
||||
|
||||
// nsIStyleRule
|
||||
virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
|
||||
virtual bool MightMapInheritedStyleData() override;
|
||||
virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
|
||||
|
@ -115,6 +134,7 @@ private:
|
|||
#endif
|
||||
nsHTMLStyleSheet* mSheet; //weak
|
||||
nsMapRuleToAttributesFunc mRuleMapper;
|
||||
RefPtr<RawServoDeclarationBlock> mServoStyle;
|
||||
void* mAttrs[1];
|
||||
};
|
||||
|
||||
|
|
|
@ -120,19 +120,6 @@ IsWebkitPrefixSupportEnabled()
|
|||
return sIsWebkitPrefixSupportEnabled;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsPrefixedPointerLockEnabled()
|
||||
{
|
||||
static bool sIsPrefixedPointerLockEnabled;
|
||||
static bool sIsPrefCached = false;
|
||||
if (!sIsPrefCached) {
|
||||
sIsPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sIsPrefixedPointerLockEnabled,
|
||||
"pointer-lock-api.prefixed.enabled");
|
||||
}
|
||||
return sIsPrefixedPointerLockEnabled;
|
||||
}
|
||||
|
||||
EventListenerManagerBase::EventListenerManagerBase()
|
||||
: mNoListenerForEvent(eVoidEvent)
|
||||
, mMayHavePaintEventListener(false)
|
||||
|
@ -1164,14 +1151,6 @@ EventListenerManager::GetLegacyEventMessage(EventMessage aEventMessage) const
|
|||
return eWebkitAnimationIteration;
|
||||
}
|
||||
}
|
||||
if (IsPrefixedPointerLockEnabled()) {
|
||||
if (aEventMessage == ePointerLockChange) {
|
||||
return eMozPointerLockChange;
|
||||
}
|
||||
if (aEventMessage == ePointerLockError) {
|
||||
return eMozPointerLockError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (aEventMessage) {
|
||||
|
|
|
@ -791,7 +791,7 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
|
|||
Preferences::GetUint("media.audio-max-decode-error", 3))
|
||||
, mVideo(this, MediaData::VIDEO_DATA,
|
||||
Preferences::GetUint("media.video-max-decode-error", 2))
|
||||
, mDemuxer(new DemuxerProxy(aDemuxer, aDecoder->AbstractMainThread()))
|
||||
, mDemuxer(nullptr)
|
||||
, mDemuxerInitDone(false)
|
||||
, mLastReportedNumDecodedFrames(0)
|
||||
, mPreviousDecodedKeyframeTime_us(sNoPreviousDecodedKeyframe)
|
||||
|
@ -804,10 +804,15 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
|
|||
MOZ_ASSERT(aDemuxer);
|
||||
MOZ_COUNT_CTOR(MediaFormatReader);
|
||||
|
||||
if (aDecoder && aDecoder->CompositorUpdatedEvent()) {
|
||||
mCompositorUpdatedListener =
|
||||
aDecoder->CompositorUpdatedEvent()->Connect(
|
||||
mTaskQueue, this, &MediaFormatReader::NotifyCompositorUpdated);
|
||||
if (aDecoder) {
|
||||
mDemuxer = MakeUnique<DemuxerProxy>(aDemuxer,
|
||||
aDecoder->AbstractMainThread());
|
||||
|
||||
if (aDecoder->CompositorUpdatedEvent()) {
|
||||
mCompositorUpdatedListener =
|
||||
aDecoder->CompositorUpdatedEvent()->Connect(
|
||||
mTaskQueue, this, &MediaFormatReader::NotifyCompositorUpdated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,13 @@ RemoteDecoderModule::SupportsMimeType(const nsACString& aMimeType,
|
|||
return mWrapped->SupportsMimeType(aMimeType, aDiagnostics);
|
||||
}
|
||||
|
||||
bool
|
||||
RemoteDecoderModule::Supports(const TrackInfo& aTrackInfo,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const
|
||||
{
|
||||
return mWrapped->Supports(aTrackInfo, aDiagnostics);
|
||||
}
|
||||
|
||||
PlatformDecoderModule::ConversionRequired
|
||||
RemoteDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
|
||||
{
|
||||
|
|
|
@ -67,6 +67,8 @@ public:
|
|||
|
||||
bool SupportsMimeType(const nsACString& aMimeType,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const override;
|
||||
bool Supports(const TrackInfo& aTrackInfo,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const override;
|
||||
|
||||
ConversionRequired DecoderNeedsConversion(
|
||||
const TrackInfo& aConfig) const override;
|
||||
|
|
|
@ -254,11 +254,7 @@ partial interface Document {
|
|||
// https://w3c.github.io/pointerlock/#extensions-to-the-documentorshadowroot-mixin
|
||||
partial interface Document {
|
||||
readonly attribute Element? pointerLockElement;
|
||||
[BinaryName="pointerLockElement", Pref="pointer-lock-api.prefixed.enabled"]
|
||||
readonly attribute Element? mozPointerLockElement;
|
||||
void exitPointerLock();
|
||||
[BinaryName="exitPointerLock", Pref="pointer-lock-api.prefixed.enabled"]
|
||||
void mozExitPointerLock();
|
||||
|
||||
// Event handlers
|
||||
attribute EventHandler onpointerlockchange;
|
||||
|
|
|
@ -260,6 +260,4 @@ partial interface Element {
|
|||
partial interface Element {
|
||||
[UnsafeInPrerendering, NeedsCallerType]
|
||||
void requestPointerLock();
|
||||
[UnsafeInPrerendering, BinaryName="requestPointerLock", Pref="pointer-lock-api.prefixed.enabled", NeedsCallerType]
|
||||
void mozRequestPointerLock();
|
||||
};
|
||||
|
|
|
@ -120,10 +120,6 @@ interface GlobalEventHandlers {
|
|||
// Document rather than here.
|
||||
attribute EventHandler onmozfullscreenchange;
|
||||
attribute EventHandler onmozfullscreenerror;
|
||||
[Pref="pointer-lock-api.prefixed.enabled"]
|
||||
attribute EventHandler onmozpointerlockchange;
|
||||
[Pref="pointer-lock-api.prefixed.enabled"]
|
||||
attribute EventHandler onmozpointerlockerror;
|
||||
|
||||
// CSS-Animation and CSS-Transition handlers.
|
||||
attribute EventHandler onanimationend;
|
||||
|
|
|
@ -77,11 +77,6 @@ dictionary MouseEventInit : EventModifierInit {
|
|||
// Mozilla extensions
|
||||
partial interface MouseEvent
|
||||
{
|
||||
[BinaryName="movementX", Pref="pointer-lock-api.prefixed.enabled"]
|
||||
readonly attribute long mozMovementX;
|
||||
[BinaryName="movementY", Pref="pointer-lock-api.prefixed.enabled"]
|
||||
readonly attribute long mozMovementY;
|
||||
|
||||
// Finger or touch pressure event value
|
||||
// ranges between 0.0 and 1.0
|
||||
readonly attribute float mozPressure;
|
||||
|
|
|
@ -57,6 +57,8 @@ for (let descriptor of WebAssembly.Module.imports(module)) {
|
|||
var instance = new WebAssembly.Instance(module, imports);
|
||||
`);
|
||||
var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0];
|
||||
assertEq(wasmScript.startLine, 1);
|
||||
assertEq(wasmScript.lineCount > 0, true);
|
||||
var lines = wasmScript.source.text.split('\n');
|
||||
var offsetsFound = 0;
|
||||
lines.forEach(function (l, n) {
|
||||
|
@ -102,6 +104,8 @@ function getWasmScriptAfterDebuggerAttached(wast) {
|
|||
|
||||
var wasmScript1 = getWasmScriptAfterDebuggerAttached('(module (func (nop)))');
|
||||
var wasmLines1 = wasmScript1.source.text.split('\n');
|
||||
assertEq(wasmScript1.startLine, 1);
|
||||
assertEq(wasmScript1.lineCount, 0);
|
||||
assertEq(wasmLines1.every((l, n) => wasmScript1.getLineOffsets(n + 1).length == 0), true);
|
||||
|
||||
// Checking that we must not resolve any location for any offset in a wasm
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// |jit-test| test-also-wasm-baseline
|
||||
// Tests debugEnabled state of wasm when allowUnobservedAsmJS == true.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
if (!wasmIsSupported())
|
||||
quit();
|
||||
|
||||
// Checking that there are no offsets are present in a wasm instance script for
|
||||
// which debug mode was not enabled.
|
||||
function getWasmScriptWithoutAllowUnobservedAsmJS(wast) {
|
||||
var sandbox = newGlobal('');
|
||||
var dbg = new Debugger();
|
||||
dbg.allowUnobservedAsmJS = true;
|
||||
dbg.addDebuggee(sandbox);
|
||||
sandbox.eval(`
|
||||
var wasm = wasmTextToBinary('${wast}');
|
||||
var m = new WebAssembly.Instance(new WebAssembly.Module(wasm));
|
||||
`);
|
||||
// Attaching after wasm instance is created.
|
||||
var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0];
|
||||
return wasmScript;
|
||||
}
|
||||
|
||||
var wasmScript1 = getWasmScriptWithoutAllowUnobservedAsmJS('(module (func (nop)))');
|
||||
var wasmLines1 = wasmScript1.source.text.split('\n');
|
||||
assertEq(wasmScript1.startLine, 1);
|
||||
assertEq(wasmScript1.lineCount, 0);
|
||||
assertEq(wasmLines1.every((l, n) => wasmScript1.getLineOffsets(n + 1).length == 0), true);
|
||||
|
||||
// Checking that we must not resolve any location for any offset in a wasm
|
||||
// instance which debug mode was not enabled.
|
||||
var wasmScript2 = getWasmScriptWithoutAllowUnobservedAsmJS('(module (func (nop)))');
|
||||
for (var i = wasmTextToBinary('(module (func (nop)))').length - 1; i >= 0; i--)
|
||||
assertThrowsInstanceOf(() => wasmScript2.getOffsetLocation(i), Error);
|
|
@ -5677,7 +5677,7 @@ struct DebuggerScriptGetLineCountMatcher
|
|||
}
|
||||
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
|
||||
uint32_t result;
|
||||
if (wasmInstance->instance().code().totalSourceLines(cx_, &result))
|
||||
if (!wasmInstance->instance().code().totalSourceLines(cx_, &result))
|
||||
return false;
|
||||
totalLines = double(result);
|
||||
return true;
|
||||
|
|
|
@ -864,12 +864,14 @@ Code::getOffsetLocation(JSContext* cx, uint32_t offset, bool* found, size_t* lin
|
|||
bool
|
||||
Code::totalSourceLines(JSContext* cx, uint32_t* count)
|
||||
{
|
||||
*count = 0;
|
||||
if (!metadata_->debugEnabled)
|
||||
return true;
|
||||
|
||||
if (!ensureSourceMap(cx))
|
||||
return false;
|
||||
|
||||
if (!maybeSourceMap_)
|
||||
*count = 0;
|
||||
else
|
||||
if (maybeSourceMap_)
|
||||
*count = maybeSourceMap_->totalLines() + experimentalWarningLinesCount;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -172,6 +172,10 @@ SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemoveProperty, void,
|
|||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, void,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
nsCSSPropertyID property)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddPresValue, void,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
nsCSSPropertyID property,
|
||||
nsCSSValueBorrowedMut css_value)
|
||||
|
||||
// CSS supports()
|
||||
SERVO_BINDING_FUNC(Servo_CSSSupports2, bool,
|
||||
|
@ -222,6 +226,8 @@ SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoComputedValuesStrong,
|
|||
RawServoStyleSetBorrowed set)
|
||||
|
||||
// Restyle the given subtree.
|
||||
// Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
|
||||
// directly
|
||||
SERVO_BINDING_FUNC(Servo_TraverseSubtree, void,
|
||||
RawGeckoElementBorrowed root, RawServoStyleSetBorrowed set,
|
||||
mozilla::TraversalRootBehavior root_behavior)
|
||||
|
|
|
@ -68,6 +68,7 @@ typedef nsTArray<const RawServoAnimationValue*> RawServoAnimationValueBorrowedLi
|
|||
#define SERVO_ARC_TYPE(name_, type_) \
|
||||
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
|
||||
DECL_BORROWED_REF_TYPE_FOR(type_) \
|
||||
DECL_BORROWED_MUT_REF_TYPE_FOR(type_) \
|
||||
struct MOZ_MUST_USE_TYPE type_##Strong \
|
||||
{ \
|
||||
type_* mPtr; \
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsMediaFeatures.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -312,7 +313,7 @@ Gecko_DropElementSnapshot(ServoElementSnapshotOwned aSnapshot)
|
|||
}
|
||||
|
||||
RawServoDeclarationBlockStrongBorrowedOrNull
|
||||
Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed aElement)
|
||||
Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
|
||||
{
|
||||
DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
|
||||
if (!decl) {
|
||||
|
@ -328,6 +329,21 @@ Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed aElement)
|
|||
(decl->AsServo()->RefRaw());
|
||||
}
|
||||
|
||||
RawServoDeclarationBlockStrongBorrowedOrNull
|
||||
Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
|
||||
{
|
||||
static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
|
||||
sizeof(RawServoDeclarationBlockStrong),
|
||||
"RefPtr should just be a pointer");
|
||||
const nsMappedAttributes* attrs = aElement->GetMappedAttributes();
|
||||
if (!attrs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const RefPtr<RawServoDeclarationBlock>& servo = attrs->GetServoStyle();
|
||||
return reinterpret_cast<const RawServoDeclarationBlockStrong*>(&servo);
|
||||
}
|
||||
|
||||
RawServoDeclarationBlockStrong
|
||||
Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
|
||||
nsIAtom* aPseudoTag,
|
||||
|
|
|
@ -158,7 +158,9 @@ SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot,
|
|||
|
||||
// Style attributes.
|
||||
RawServoDeclarationBlockStrongBorrowedOrNull
|
||||
Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed element);
|
||||
Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed element);
|
||||
RawServoDeclarationBlockStrongBorrowedOrNull
|
||||
Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed element);
|
||||
|
||||
// Animations
|
||||
RawServoDeclarationBlockStrong
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsAnimationManager.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
#include "nsIDocumentInlines.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStyleContext.h"
|
||||
|
@ -127,6 +128,8 @@ ServoStyleSet::GetContext(nsIContent* aContent,
|
|||
MOZ_ASSERT(aContent->IsElement());
|
||||
Element* element = aContent->AsElement();
|
||||
|
||||
|
||||
ResolveMappedAttrDeclarationBlocks();
|
||||
RefPtr<ServoComputedValues> computedValues;
|
||||
if (aMayCompute == LazyComputeBehavior::Allow) {
|
||||
computedValues =
|
||||
|
@ -176,6 +179,21 @@ ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
|
|||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::ResolveMappedAttrDeclarationBlocks()
|
||||
{
|
||||
if (nsHTMLStyleSheet* sheet = mPresContext->Document()->GetAttributeStyleSheet()) {
|
||||
sheet->CalculateMappedServoDeclarations();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
|
||||
mozilla::TraversalRootBehavior aRootBehavior) {
|
||||
ResolveMappedAttrDeclarationBlocks();
|
||||
Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior);
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleContext>
|
||||
ServoStyleSet::ResolveStyleFor(Element* aElement,
|
||||
nsStyleContext* aParentContext,
|
||||
|
@ -541,7 +559,7 @@ ServoStyleSet::StyleDocument()
|
|||
DocumentStyleRootIterator iter(mPresContext->Document());
|
||||
while (Element* root = iter.GetNextStyleRoot()) {
|
||||
if (root->ShouldTraverseForServo()) {
|
||||
Servo_TraverseSubtree(root, mRawSet.get(), TraversalRootBehavior::Normal);
|
||||
PrepareAndTraverseSubtree(root, TraversalRootBehavior::Normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -550,14 +568,13 @@ void
|
|||
ServoStyleSet::StyleNewSubtree(Element* aRoot)
|
||||
{
|
||||
MOZ_ASSERT(!aRoot->HasServoData());
|
||||
Servo_TraverseSubtree(aRoot, mRawSet.get(), TraversalRootBehavior::Normal);
|
||||
PrepareAndTraverseSubtree(aRoot, TraversalRootBehavior::Normal);
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::StyleNewChildren(Element* aParent)
|
||||
{
|
||||
Servo_TraverseSubtree(aParent, mRawSet.get(),
|
||||
TraversalRootBehavior::UnstyledChildrenOnly);
|
||||
PrepareAndTraverseSubtree(aParent, TraversalRootBehavior::UnstyledChildrenOnly);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -199,6 +199,20 @@ private:
|
|||
CSSPseudoElementType aPseudoType,
|
||||
LazyComputeBehavior aMayCompute);
|
||||
|
||||
/**
|
||||
* Resolve all ServoDeclarationBlocks attached to mapped
|
||||
* presentation attributes cached on the document.
|
||||
* Call this before jumping into Servo's style system.
|
||||
*/
|
||||
void ResolveMappedAttrDeclarationBlocks();
|
||||
|
||||
/**
|
||||
* Perform all lazy operations required before traversing
|
||||
* a subtree.
|
||||
*/
|
||||
void PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
|
||||
mozilla::TraversalRootBehavior aRootBehavior);
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
UniquePtr<RawServoStyleSet> mRawSet;
|
||||
EnumeratedArray<SheetType, SheetType::Count,
|
||||
|
|
|
@ -289,6 +289,7 @@ nsHTMLStyleSheet::nsHTMLStyleSheet(nsIDocument* aDocument)
|
|||
, mTableQuirkColorRule(new TableQuirkColorRule())
|
||||
, mTableTHRule(new TableTHRule())
|
||||
, mMappedAttrTable(&MappedAttrTable_Ops, sizeof(MappedAttrTableEntry))
|
||||
, mMappedAttrsDirty(false)
|
||||
, mLangRuleTable(&LangRuleTable_Ops, sizeof(LangRuleTableEntry))
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
@ -478,6 +479,7 @@ nsHTMLStyleSheet::Reset()
|
|||
|
||||
mLangRuleTable.Clear();
|
||||
mMappedAttrTable.Clear();
|
||||
mMappedAttrsDirty = false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -526,6 +528,7 @@ nsHTMLStyleSheet::SetVisitedLinkColor(nscolor aColor)
|
|||
already_AddRefed<nsMappedAttributes>
|
||||
nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped)
|
||||
{
|
||||
mMappedAttrsDirty = true;
|
||||
auto entry = static_cast<MappedAttrTableEntry*>
|
||||
(mMappedAttrTable.Add(aMapped, fallible));
|
||||
if (!entry)
|
||||
|
@ -542,7 +545,6 @@ void
|
|||
nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(aMapped);
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t entryCount = mMappedAttrTable.EntryCount() - 1;
|
||||
#endif
|
||||
|
@ -552,6 +554,97 @@ nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped)
|
|||
NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed");
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Struct containing once-initialized information about
|
||||
// our synthesized rule data
|
||||
struct StaticRuleDataInfo
|
||||
{
|
||||
// the bitmask used.
|
||||
uint64_t mMask;
|
||||
// the number of properties contained
|
||||
size_t mPropCount;
|
||||
// offset of given style struct in array
|
||||
size_t mOffsets[nsStyleStructID_Length];
|
||||
// location of property in given array
|
||||
nsCSSPropertyID* mIndexToPropertyMapping;
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
CalculateIndexArray(StaticRuleDataInfo* aInfo)
|
||||
{
|
||||
// this will leak at shutdown, but it's not much and this code is temporary
|
||||
// anyway.
|
||||
aInfo->mIndexToPropertyMapping = new nsCSSPropertyID[aInfo->mPropCount];
|
||||
size_t structOffset;
|
||||
size_t propertyIndex;
|
||||
#define CSS_PROP_LIST_EXCLUDE_LOGICAL
|
||||
#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \
|
||||
kwtable_, stylestruct_, stylestructoffset_, animtype_) \
|
||||
structOffset = aInfo->mOffsets[eStyleStruct_##stylestruct_]; \
|
||||
propertyIndex = nsCSSProps::PropertyIndexInStruct(eCSSProperty_##id_); \
|
||||
aInfo->mIndexToPropertyMapping[structOffset + propertyIndex] = eCSSProperty_##id_;
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP
|
||||
#undef CSS_PROP_LIST_EXCLUDE_LOGICAL
|
||||
}
|
||||
|
||||
static StaticRuleDataInfo
|
||||
CalculateRuleDataInfo()
|
||||
{
|
||||
StaticRuleDataInfo sizes;
|
||||
sizes.mMask = 0;
|
||||
sizes.mPropCount = 0;
|
||||
#define STYLE_STRUCT(name, checkdata_cb) \
|
||||
sizes.mMask |= NS_STYLE_INHERIT_BIT(name); \
|
||||
sizes.mOffsets[eStyleStruct_##name] = sizes.mPropCount; \
|
||||
sizes.mPropCount += nsCSSProps::PropertyCountInStruct(eStyleStruct_##name);
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
|
||||
CalculateIndexArray(&sizes);
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsHTMLStyleSheet::CalculateMappedServoDeclarations()
|
||||
{
|
||||
// avoid recalculating or reallocating
|
||||
static StaticRuleDataInfo sizes = CalculateRuleDataInfo();
|
||||
|
||||
if (!mMappedAttrsDirty) {
|
||||
return;
|
||||
}
|
||||
mMappedAttrsDirty = false;
|
||||
|
||||
void* dataStorage = alloca(sizes.mPropCount * sizeof(nsCSSValue));
|
||||
for (auto iter = mMappedAttrTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
|
||||
if (attr->mAttributes->GetServoStyle()) {
|
||||
// Only handle cases which haven't been filled in already
|
||||
continue;
|
||||
}
|
||||
// Construction cleans up any values we may have set
|
||||
AutoCSSValueArray dataArray(dataStorage, sizes.mPropCount);
|
||||
|
||||
// synthesized ruleData
|
||||
// we pass null for the style context because the code we call into
|
||||
// doesn't deal with the style context. This is temporary.
|
||||
nsRuleData ruleData(sizes.mMask, dataArray.get(),
|
||||
mDocument->GetShell()->GetPresContext(), nullptr);
|
||||
// Copy the offsets; ruleData won't know where to find properties otherwise
|
||||
mozilla::PodCopy(ruleData.mValueOffsets,
|
||||
sizes.mOffsets,
|
||||
nsStyleStructID_Length);
|
||||
attr->mAttributes->LazilyResolveServoDeclaration(&ruleData,
|
||||
sizes.mIndexToPropertyMapping,
|
||||
sizes.mPropCount);
|
||||
}
|
||||
}
|
||||
|
||||
nsIStyleRule*
|
||||
nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage)
|
||||
{
|
||||
|
|
|
@ -62,6 +62,10 @@ public:
|
|||
already_AddRefed<nsMappedAttributes>
|
||||
UniqueMappedAttributes(nsMappedAttributes* aMapped);
|
||||
void DropMappedAttributes(nsMappedAttributes* aMapped);
|
||||
// For each mapped presentation attribute in the cache, resolve
|
||||
// the attached ServoDeclarationBlock by running the mapping
|
||||
// and converting the ruledata to Servo specified values.
|
||||
void CalculateMappedServoDeclarations();
|
||||
|
||||
nsIStyleRule* LangRuleFor(const nsString& aLanguage);
|
||||
|
||||
|
@ -175,6 +179,10 @@ private:
|
|||
RefPtr<TableTHRule> mTableTHRule;
|
||||
|
||||
PLDHashTable mMappedAttrTable;
|
||||
// Whether or not the mapped attributes table
|
||||
// has been changed since the last call to
|
||||
// CalculateMappedServoDeclarations()
|
||||
bool mMappedAttrsDirty;
|
||||
PLDHashTable mLangRuleTable;
|
||||
};
|
||||
|
||||
|
|
|
@ -2354,44 +2354,25 @@ UnsetPropertiesWithoutFlags(const nsStyleStructID aSID,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We allocate arrays of CSS values with alloca. (These arrays are a
|
||||
* fixed size per style struct, but we don't want to waste the
|
||||
* allocation and construction/destruction costs of the big structs when
|
||||
* we're handling much smaller ones.) Since the lifetime of an alloca
|
||||
* allocation is the life of the calling function, the caller must call
|
||||
* alloca. However, to ensure that constructors and destructors are
|
||||
* balanced, we do the constructor and destructor calling from this RAII
|
||||
* class, AutoCSSValueArray.
|
||||
*/
|
||||
struct AutoCSSValueArray {
|
||||
/**
|
||||
* aStorage must be the result of alloca(aCount * sizeof(nsCSSValue))
|
||||
*/
|
||||
AutoCSSValueArray(void* aStorage, size_t aCount) {
|
||||
MOZ_ASSERT(size_t(aStorage) % NS_ALIGNMENT_OF(nsCSSValue) == 0,
|
||||
"bad alignment from alloca");
|
||||
mCount = aCount;
|
||||
// Don't use placement new[], since it might store extra data
|
||||
// for the count (on Windows!).
|
||||
mArray = static_cast<nsCSSValue*>(aStorage);
|
||||
for (size_t i = 0; i < mCount; ++i) {
|
||||
new (KnownNotNull, mArray + i) nsCSSValue();
|
||||
}
|
||||
AutoCSSValueArray::AutoCSSValueArray(void* aStorage, size_t aCount)
|
||||
{
|
||||
MOZ_ASSERT(size_t(aStorage) % NS_ALIGNMENT_OF(nsCSSValue) == 0,
|
||||
"bad alignment from alloca");
|
||||
mCount = aCount;
|
||||
// Don't use placement new[], since it might store extra data
|
||||
// for the count (on Windows!).
|
||||
mArray = static_cast<nsCSSValue*>(aStorage);
|
||||
for (size_t i = 0; i < mCount; ++i) {
|
||||
new (KnownNotNull, mArray + i) nsCSSValue();
|
||||
}
|
||||
}
|
||||
|
||||
~AutoCSSValueArray() {
|
||||
for (size_t i = 0; i < mCount; ++i) {
|
||||
mArray[i].~nsCSSValue();
|
||||
}
|
||||
AutoCSSValueArray::~AutoCSSValueArray()
|
||||
{
|
||||
for (size_t i = 0; i < mCount; ++i) {
|
||||
mArray[i].~nsCSSValue();
|
||||
}
|
||||
|
||||
nsCSSValue* get() { return mArray; }
|
||||
|
||||
private:
|
||||
nsCSSValue *mArray;
|
||||
size_t mCount;
|
||||
};
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
|
||||
|
|
|
@ -1085,4 +1085,30 @@ private:
|
|||
void* aStruct);
|
||||
};
|
||||
|
||||
/**
|
||||
* We allocate arrays of CSS values with alloca. (These arrays are a
|
||||
* fixed size per style struct, but we don't want to waste the
|
||||
* allocation and construction/destruction costs of the big structs when
|
||||
* we're handling much smaller ones.) Since the lifetime of an alloca
|
||||
* allocation is the life of the calling function, the caller must call
|
||||
* alloca. However, to ensure that constructors and destructors are
|
||||
* balanced, we do the constructor and destructor calling from this RAII
|
||||
* class, AutoCSSValueArray.
|
||||
*/
|
||||
struct AutoCSSValueArray
|
||||
{
|
||||
/**
|
||||
* aStorage must be the result of alloca(aCount * sizeof(nsCSSValue))
|
||||
*/
|
||||
AutoCSSValueArray(void* aStorage, size_t aCount);
|
||||
|
||||
~AutoCSSValueArray();
|
||||
|
||||
nsCSSValue* get() { return mArray; }
|
||||
|
||||
private:
|
||||
nsCSSValue *mArray;
|
||||
size_t mCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -88,5 +88,6 @@ class ReftestCommands(object):
|
|||
description='Run the reftest harness.',
|
||||
parser=setup_argument_parser)
|
||||
def reftest(self, **kwargs):
|
||||
self.context.activate_mozharness_venv()
|
||||
kwargs['suite'] = 'reftest'
|
||||
return run_reftest(self.context, **kwargs)
|
||||
|
|
|
@ -45,11 +45,15 @@ AnnexB::ConvertSampleToAnnexB(mozilla::MediaRawData* aSample, bool aAddSPS)
|
|||
uint32_t nalLen = reader.ReadU32();
|
||||
const uint8_t* p = reader.Read(nalLen);
|
||||
|
||||
writer.Write(kAnnexBDelimiter, ArrayLength(kAnnexBDelimiter));
|
||||
if (!writer.Write(kAnnexBDelimiter, ArrayLength(kAnnexBDelimiter))) {
|
||||
return false;
|
||||
}
|
||||
if (!p) {
|
||||
break;
|
||||
}
|
||||
writer.Write(p, nalLen);
|
||||
if (!writer.Write(p, nalLen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
|
||||
|
@ -188,7 +192,7 @@ FindStartCode(ByteReader& aBr, size_t& aStartSize)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
ParseNALUnits(ByteWriter& aBw, ByteReader& aBr)
|
||||
{
|
||||
size_t startSize;
|
||||
|
@ -200,17 +204,22 @@ ParseNALUnits(ByteWriter& aBw, ByteReader& aBr)
|
|||
size_t offset = aBr.Offset();
|
||||
size_t sizeNAL = offset - startOffset - startSize;
|
||||
aBr.Seek(startOffset);
|
||||
aBw.WriteU32(sizeNAL);
|
||||
aBw.Write(aBr.Read(sizeNAL), sizeNAL);
|
||||
if (!aBw.WriteU32(sizeNAL)
|
||||
|| !aBw.Write(aBr.Read(sizeNAL), sizeNAL)) {
|
||||
return false;
|
||||
}
|
||||
aBr.Read(startSize);
|
||||
startOffset = offset;
|
||||
}
|
||||
}
|
||||
size_t sizeNAL = aBr.Remaining();
|
||||
if (sizeNAL) {
|
||||
aBw.WriteU32(sizeNAL);
|
||||
aBw.Write(aBr.Read(sizeNAL), sizeNAL);
|
||||
if (!aBw.WriteU32(sizeNAL)
|
||||
|| !aBw.Write(aBr.Read(sizeNAL), sizeNAL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -228,7 +237,9 @@ AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample)
|
|||
ByteWriter writer(nalu);
|
||||
ByteReader reader(aSample->Data(), aSample->Size());
|
||||
|
||||
ParseNALUnits(writer, reader);
|
||||
if (!ParseNALUnits(writer, reader)) {
|
||||
return false;
|
||||
}
|
||||
nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
|
||||
return samplewriter->Replace(nalu.begin(), nalu.length());
|
||||
}
|
||||
|
@ -284,12 +295,16 @@ AnnexB::ExtractExtraData(const mozilla::MediaRawData* aSample)
|
|||
|
||||
if (nalType == 0x7) { /* SPS */
|
||||
numSps++;
|
||||
spsw.WriteU16(nalLen);
|
||||
spsw.Write(p, nalLen);
|
||||
if (!spsw.WriteU16(nalLen)
|
||||
|| !spsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
} else if (nalType == 0x8) { /* PPS */
|
||||
numPps++;
|
||||
ppsw.WriteU16(nalLen);
|
||||
ppsw.Write(p, nalLen);
|
||||
if (!ppsw.WriteU16(nalLen)
|
||||
|| !ppsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,8 +414,10 @@ AnnexB::ConvertSampleTo4BytesAVCC(mozilla::MediaRawData* aSample)
|
|||
if (!p) {
|
||||
return true;
|
||||
}
|
||||
writer.WriteU32(nalLen);
|
||||
writer.Write(p, nalLen);
|
||||
if (!writer.WriteU32(nalLen)
|
||||
|| !writer.Write(p, nalLen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
|
||||
return samplewriter->Replace(dest.begin(), dest.length());
|
||||
|
|
|
@ -22,49 +22,49 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void WriteU8(uint8_t aByte)
|
||||
MOZ_MUST_USE bool WriteU8(uint8_t aByte)
|
||||
{
|
||||
Write(&aByte, 1);
|
||||
return Write(&aByte, 1);
|
||||
}
|
||||
|
||||
void WriteU16(uint16_t aShort)
|
||||
MOZ_MUST_USE bool WriteU16(uint16_t aShort)
|
||||
{
|
||||
uint8_t c[2];
|
||||
mozilla::BigEndian::writeUint16(&c[0], aShort);
|
||||
Write(&c[0], 2);
|
||||
return Write(&c[0], 2);
|
||||
}
|
||||
|
||||
void WriteU32(uint32_t aLong)
|
||||
MOZ_MUST_USE bool WriteU32(uint32_t aLong)
|
||||
{
|
||||
uint8_t c[4];
|
||||
mozilla::BigEndian::writeUint32(&c[0], aLong);
|
||||
Write(&c[0], 4);
|
||||
return Write(&c[0], 4);
|
||||
}
|
||||
|
||||
void Write32(int32_t aLong)
|
||||
MOZ_MUST_USE bool Write32(int32_t aLong)
|
||||
{
|
||||
uint8_t c[4];
|
||||
mozilla::BigEndian::writeInt32(&c[0], aLong);
|
||||
Write(&c[0], 4);
|
||||
return Write(&c[0], 4);
|
||||
}
|
||||
|
||||
void WriteU64(uint64_t aLongLong)
|
||||
MOZ_MUST_USE bool WriteU64(uint64_t aLongLong)
|
||||
{
|
||||
uint8_t c[8];
|
||||
mozilla::BigEndian::writeUint64(&c[0], aLongLong);
|
||||
Write(&c[0], 8);
|
||||
return Write(&c[0], 8);
|
||||
}
|
||||
|
||||
void Write64(int64_t aLongLong)
|
||||
MOZ_MUST_USE bool Write64(int64_t aLongLong)
|
||||
{
|
||||
uint8_t c[8];
|
||||
mozilla::BigEndian::writeInt64(&c[0], aLongLong);
|
||||
Write(&c[0], 8);
|
||||
return Write(&c[0], 8);
|
||||
}
|
||||
|
||||
void Write(const uint8_t* aSrc, size_t aCount)
|
||||
MOZ_MUST_USE bool Write(const uint8_t* aSrc, size_t aCount)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mPtr.append(aSrc, aCount));
|
||||
return mPtr.append(aSrc, aCount);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -37,6 +37,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
|
@ -199,16 +200,22 @@ public class SwitchBoard {
|
|||
return experiment;
|
||||
}
|
||||
|
||||
private static boolean isMatch(Context c, @Nullable JSONObject matchKeys) {
|
||||
/**
|
||||
* Return false if the match object contains any non-matching patterns. Otherwise returns true.
|
||||
*/
|
||||
private static boolean isMatch(Context context, @Nullable JSONObject matchKeys) {
|
||||
// If no match keys are specified, default to enabling the experiment.
|
||||
if (matchKeys == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (matchKeys.has(KEY_APP_ID)) {
|
||||
final String packageName = c.getPackageName();
|
||||
try {
|
||||
if (!packageName.matches(matchKeys.getString(KEY_APP_ID))) {
|
||||
final String packageName = context.getPackageName();
|
||||
final String expectedAppIdPattern = matchKeys.getString(KEY_APP_ID);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedAppIdPattern)
|
||||
&& !packageName.matches(expectedAppIdPattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
|
@ -219,7 +226,10 @@ public class SwitchBoard {
|
|||
if (matchKeys.has(KEY_COUNTRY)) {
|
||||
try {
|
||||
final String country = Locale.getDefault().getISO3Country();
|
||||
if (!country.matches(matchKeys.getString(KEY_COUNTRY))) {
|
||||
final String expectedCountryPattern = matchKeys.getString(KEY_COUNTRY);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedCountryPattern)
|
||||
&& !country.matches(expectedCountryPattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (MissingResourceException | JSONException e) {
|
||||
|
@ -228,30 +238,40 @@ public class SwitchBoard {
|
|||
}
|
||||
|
||||
if (matchKeys.has(KEY_DEVICE)) {
|
||||
final String device = Build.DEVICE;
|
||||
try {
|
||||
if (!device.matches(matchKeys.getString(KEY_DEVICE))) {
|
||||
final String device = Build.DEVICE;
|
||||
final String expectedDevicePattern = matchKeys.getString(KEY_DEVICE);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedDevicePattern)
|
||||
&& !device.matches(expectedDevicePattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Exception matching device", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (matchKeys.has(KEY_LANG)) {
|
||||
try {
|
||||
final String lang = Locale.getDefault().getISO3Language();
|
||||
if (!lang.matches(matchKeys.getString(KEY_LANG))) {
|
||||
final String expectedLanguagePattern = matchKeys.getString(KEY_LANG);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedLanguagePattern)
|
||||
&& !lang.matches(expectedLanguagePattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (MissingResourceException | JSONException e) {
|
||||
Log.e(TAG, "Exception matching lang", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (matchKeys.has(KEY_MANUFACTURER)) {
|
||||
final String manufacturer = Build.MANUFACTURER;
|
||||
try {
|
||||
if (!manufacturer.matches(matchKeys.getString(KEY_MANUFACTURER))) {
|
||||
final String manufacturer = Build.MANUFACTURER;
|
||||
final String expectedManufacturerPattern = matchKeys.getString(KEY_MANUFACTURER);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedManufacturerPattern)
|
||||
&& !manufacturer.matches(expectedManufacturerPattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
|
@ -261,8 +281,11 @@ public class SwitchBoard {
|
|||
|
||||
if (matchKeys.has(KEY_VERSION)) {
|
||||
try {
|
||||
final String version = c.getPackageManager().getPackageInfo(c.getPackageName(), 0).versionName;
|
||||
if (!version.matches(matchKeys.getString(KEY_VERSION))) {
|
||||
final String version = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
|
||||
final String expectedVersionPattern = matchKeys.getString(KEY_VERSION);
|
||||
|
||||
if (!TextUtils.isEmpty(expectedVersionPattern)
|
||||
&& !version.matches(expectedVersionPattern)) {
|
||||
return false;
|
||||
}
|
||||
} catch (NameNotFoundException | JSONException e) {
|
||||
|
|
|
@ -4818,7 +4818,6 @@ pref("full-screen-api.warning.timeout", 3000);
|
|||
pref("full-screen-api.warning.delay", 500);
|
||||
|
||||
// DOM pointerlock API
|
||||
pref("pointer-lock-api.prefixed.enabled", false);
|
||||
// time for the warning box stays on the screen before sliding out, unit: ms
|
||||
pref("pointer-lock-api.warning.timeout", 3000);
|
||||
|
||||
|
|
|
@ -19,11 +19,13 @@ linux32/debug:
|
|||
build-platform: linux/debug
|
||||
test-sets:
|
||||
- linux32-tests
|
||||
- external-media-tests
|
||||
linux32/opt:
|
||||
build-platform: linux/opt
|
||||
test-sets:
|
||||
- linux32-tests
|
||||
- linux32-opt-tests
|
||||
- external-media-tests
|
||||
|
||||
linux64/debug:
|
||||
build-platform: linux64/debug
|
||||
|
@ -84,10 +86,12 @@ windows7-32-vm/debug:
|
|||
build-platform: win32/debug
|
||||
test-sets:
|
||||
- windows-vm-tests
|
||||
- external-media-tests
|
||||
windows7-32-vm/opt:
|
||||
build-platform: win32/opt
|
||||
test-sets:
|
||||
- windows-vm-tests
|
||||
- external-media-tests
|
||||
|
||||
# win32 gpu
|
||||
#windows7-32/debug:
|
||||
|
@ -104,10 +108,12 @@ windows10-64-vm/debug:
|
|||
build-platform: win64/debug
|
||||
test-sets:
|
||||
- windows-vm-tests
|
||||
- external-media-tests
|
||||
windows10-64-vm/opt:
|
||||
build-platform: win64/opt
|
||||
test-sets:
|
||||
- windows-vm-tests
|
||||
- external-media-tests
|
||||
|
||||
# win64 gpu
|
||||
#windows10-64/debug:
|
||||
|
|
|
@ -44,7 +44,9 @@ web-platform-tests:
|
|||
- web-platform-tests-wdspec
|
||||
|
||||
external-media-tests:
|
||||
- external-media-tests
|
||||
- external-media-tests-base
|
||||
- external-media-tests-youtube
|
||||
- external-media-tests-twitch
|
||||
|
||||
opt-only-tests:
|
||||
- mochitest-valgrind
|
||||
|
@ -88,7 +90,6 @@ jsdcov-code-coverage-tests:
|
|||
windows-vm-tests:
|
||||
- cppunit
|
||||
#- crashtest
|
||||
- external-media-tests
|
||||
#- gtest
|
||||
#- jittest
|
||||
- jsreftest
|
||||
|
@ -147,7 +148,6 @@ macosx64-tests-talos:
|
|||
linux32-tests:
|
||||
- cppunit
|
||||
- crashtest
|
||||
- external-media-tests
|
||||
- firefox-ui-functional-local
|
||||
- firefox-ui-functional-remote
|
||||
- gtest
|
||||
|
|
|
@ -89,7 +89,7 @@ crashtest:
|
|||
extra-options:
|
||||
- --reftest-suite=crashtest
|
||||
|
||||
external-media-tests:
|
||||
external-media-tests-base:
|
||||
description: "External Media Test run"
|
||||
suite: external-media-tests
|
||||
treeherder-symbol: tc-VP(b-m)
|
||||
|
@ -111,6 +111,54 @@ external-media-tests:
|
|||
- mediatests/taskcluster_posix_config.py
|
||||
- remove_executables.py
|
||||
|
||||
external-media-tests-twitch:
|
||||
description: "External Media Test Twitch run"
|
||||
suite: external-media-tests/twitch
|
||||
treeherder-symbol: tc-VP(b-t)
|
||||
e10s: false
|
||||
tier: 2
|
||||
max-run-time: 5400
|
||||
docker-image: {"in-tree": "desktop1604-test"}
|
||||
run-on-projects:
|
||||
by-test-platform:
|
||||
windows.*: ['mozilla-central', 'try']
|
||||
default: ['all']
|
||||
mozharness:
|
||||
script: firefox_media_tests_taskcluster.py
|
||||
config:
|
||||
by-test-platform:
|
||||
windows.*:
|
||||
- mediatests/taskcluster_windows_config.py
|
||||
default:
|
||||
- mediatests/taskcluster_posix_config.py
|
||||
- remove_executables.py
|
||||
extra-options:
|
||||
- "--suite=media-twitch-tests"
|
||||
|
||||
external-media-tests-youtube:
|
||||
description: "External Media Test Youtube run"
|
||||
suite: external-media-tests/youtube
|
||||
treeherder-symbol: tc-VP(b-y)
|
||||
e10s: false
|
||||
tier: 2
|
||||
max-run-time: 5400
|
||||
docker-image: {"in-tree": "desktop1604-test"}
|
||||
run-on-projects:
|
||||
by-test-platform:
|
||||
windows.*: ['mozilla-central', 'try']
|
||||
default: ['all']
|
||||
mozharness:
|
||||
script: firefox_media_tests_taskcluster.py
|
||||
config:
|
||||
by-test-platform:
|
||||
windows.*:
|
||||
- mediatests/taskcluster_windows_config.py
|
||||
default:
|
||||
- mediatests/taskcluster_posix_config.py
|
||||
- remove_executables.py
|
||||
extra-options:
|
||||
- "--suite=media-youtube-tests"
|
||||
|
||||
firefox-ui-functional-local:
|
||||
description: "Firefox-ui-tests functional run"
|
||||
suite: "firefox-ui/functional local"
|
||||
|
|
|
@ -58,13 +58,6 @@ def setup():
|
|||
os.remove(mach_dest)
|
||||
os.symlink(mach_src, mach_dest)
|
||||
|
||||
activate = os.path.join(build_dir, 'venv', 'bin', 'activate')
|
||||
if os.path.isfile(activate):
|
||||
# TODO Support other shells
|
||||
bashrc = os.path.expanduser(os.path.join('~', '.bashrc'))
|
||||
with open(bashrc, 'ab') as f:
|
||||
f.write(". {}".format(activate))
|
||||
|
||||
print("""
|
||||
Mozharness has finished downloading the build and tests to:
|
||||
{}
|
||||
|
|
|
@ -68,7 +68,7 @@ def target_tasks_default(full_task_graph, parameters):
|
|||
"""Target the tasks which have indicated they should be run on this project
|
||||
via the `run_on_projects` attributes."""
|
||||
def filter(task):
|
||||
run_on_projects = set(t.attributes.get('run_on_projects', []))
|
||||
run_on_projects = set(task.attributes.get('run_on_projects', []))
|
||||
if 'all' in run_on_projects:
|
||||
return True
|
||||
project = parameters['project']
|
||||
|
|
|
@ -425,7 +425,7 @@ action.InputState = {};
|
|||
/**
|
||||
* Input state associated with a keyboard-type device.
|
||||
*/
|
||||
action.InputState.Key = class extends InputState {
|
||||
action.InputState.Key = class Key extends InputState {
|
||||
constructor() {
|
||||
super();
|
||||
this.pressed = new Set();
|
||||
|
@ -498,7 +498,7 @@ action.InputState.Key = class extends InputState {
|
|||
/**
|
||||
* Input state not associated with a specific physical device.
|
||||
*/
|
||||
action.InputState.Null = class extends InputState {
|
||||
action.InputState.Null = class Null extends InputState {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = "none";
|
||||
|
@ -513,7 +513,7 @@ action.InputState.Null = class extends InputState {
|
|||
* @param {boolean} primary
|
||||
* Whether the pointing device is primary.
|
||||
*/
|
||||
action.InputState.Pointer = class extends InputState {
|
||||
action.InputState.Pointer = class Pointer extends InputState {
|
||||
constructor(subtype, primary) {
|
||||
super();
|
||||
this.pressed = new Set();
|
||||
|
|
|
@ -64,4 +64,5 @@ class MachCommands(object):
|
|||
'using marionette).',
|
||||
parser=setup_marionette_argument_parser)
|
||||
def run_marionette_test(self, **kwargs):
|
||||
self.context.activate_mozharness_venv()
|
||||
return run_marionette(self.context, **kwargs)
|
||||
|
|
|
@ -15,7 +15,7 @@ action.inputStateMap = new Map();
|
|||
add_test(function test_createAction() {
|
||||
Assert.throws(() => new action.Action(), InvalidArgumentError,
|
||||
"Missing Action constructor args");
|
||||
Assert.throws(() => new action.Action(1,2), InvalidArgumentError,
|
||||
Assert.throws(() => new action.Action(1, 2), InvalidArgumentError,
|
||||
"Missing Action constructor args");
|
||||
Assert.throws(
|
||||
() => new action.Action(1, 2, "sometype"), /Expected string/, "Non-string arguments.");
|
||||
|
@ -157,7 +157,7 @@ add_test(function test_processPointerAction() {
|
|||
pointerType: "touch",
|
||||
primary: false,
|
||||
},
|
||||
}
|
||||
};
|
||||
let actionItems = [
|
||||
{
|
||||
duration: 2000,
|
||||
|
@ -364,7 +364,7 @@ add_test(function test_processPointerActionInputStateMap() {
|
|||
let parameters = {pointerType: "mouse", primary: false};
|
||||
let a = new action.Action(id, "pointer", actionItem.type);
|
||||
let wrongInputState = new action.InputState.Pointer("pause", true);
|
||||
action.inputStateMap.set(id, wrongInputState)
|
||||
action.inputStateMap.set(id, wrongInputState);
|
||||
checkErrors(
|
||||
/to be mapped to InputState whose subtype is/, action.processPointerAction,
|
||||
[id, parameters, a],
|
||||
|
@ -378,9 +378,22 @@ add_test(function test_processPointerActionInputStateMap() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_createInputState() {
|
||||
for (let kind in action.InputState) {
|
||||
let state = new action.InputState[kind]();
|
||||
ok(state);
|
||||
if (kind === "Null") {
|
||||
equal(state.type, "none");
|
||||
} else {
|
||||
equal(state.type, kind.toLowerCase());
|
||||
}
|
||||
}
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_extractActionChainValidation() {
|
||||
for (let actions of [-1, "a", undefined, null]) {
|
||||
let message = `actions: ${getTypeString(actions)}`
|
||||
let message = `actions: ${getTypeString(actions)}`;
|
||||
Assert.throws(() => action.Chain.fromJson(actions),
|
||||
InvalidArgumentError, message);
|
||||
Assert.throws(() => action.Chain.fromJson(actions),
|
||||
|
|
|
@ -38,6 +38,7 @@ module.exports = {
|
|||
"is": false,
|
||||
"isnot": false,
|
||||
"ok": false,
|
||||
"PromiseDebugging": false,
|
||||
"privateNoteIntentionalCrash": false,
|
||||
"registerCleanupFunction": false,
|
||||
"requestLongerTimeout": false,
|
||||
|
|
|
@ -93,4 +93,5 @@ class MochitestCommands(object):
|
|||
description='Run the mochitest harness.',
|
||||
parser=setup_argument_parser)
|
||||
def mochitest(self, **kwargs):
|
||||
self.context.activate_mozharness_venv()
|
||||
return run_mochitest(self.context, **kwargs)
|
||||
|
|
|
@ -76,6 +76,9 @@ CATEGORIES = {
|
|||
}
|
||||
|
||||
|
||||
IS_WIN = sys.platform in ('win32', 'cygwin')
|
||||
|
||||
|
||||
def ancestors(path, depth=0):
|
||||
"""Emit the parent directories of a path."""
|
||||
count = 1
|
||||
|
@ -88,6 +91,32 @@ def ancestors(path, depth=0):
|
|||
count += 1
|
||||
|
||||
|
||||
def activate_mozharness_venv(context):
|
||||
"""Activate the mozharness virtualenv in-process."""
|
||||
venv = os.path.join(context.mozharness_workdir,
|
||||
context.mozharness_config.get('virtualenv_path', 'venv'))
|
||||
|
||||
if not os.path.isdir(venv):
|
||||
print("No mozharness virtualenv detected at '{}'.".format(venv))
|
||||
return 1
|
||||
|
||||
venv_bin = os.path.join(venv, 'Scripts' if IS_WIN else 'bin')
|
||||
activate_path = os.path.join(venv_bin, 'activate_this.py')
|
||||
|
||||
execfile(activate_path, dict(__file__=activate_path))
|
||||
|
||||
if isinstance(os.environ['PATH'], unicode):
|
||||
os.environ['PATH'] = os.environ['PATH'].encode('utf-8')
|
||||
|
||||
# sys.executable is used by mochitest-media to start the websocketprocessbridge,
|
||||
# for some reason it doesn't get set when calling `activate_this.py` so set it
|
||||
# here instead.
|
||||
binary = 'python'
|
||||
if IS_WIN:
|
||||
binary += '.exe'
|
||||
sys.executable = os.path.join(venv_bin, binary)
|
||||
|
||||
|
||||
def find_firefox(context):
|
||||
"""Try to automagically find the firefox binary."""
|
||||
import mozinstall
|
||||
|
@ -176,6 +205,9 @@ def bootstrap(test_package_root):
|
|||
if config:
|
||||
return os.path.join(config['base_work_dir'], config['work_dir'])
|
||||
|
||||
if key == 'activate_mozharness_venv':
|
||||
return types.MethodType(activate_mozharness_venv, context)
|
||||
|
||||
mach = mach.main.Mach(os.getcwd())
|
||||
mach.populate_context_handler = populate_context
|
||||
|
||||
|
|
|
@ -61,4 +61,5 @@ class MochitestCommands(object):
|
|||
description='Run the xpcshell harness.',
|
||||
parser=parser_desktop)
|
||||
def xpcshell(self, **kwargs):
|
||||
self.context.activate_mozharness_venv()
|
||||
return run_xpcshell(self.context, **kwargs)
|
||||
|
|
|
@ -52,6 +52,7 @@ module.exports = {
|
|||
"notEqual": false,
|
||||
"notStrictEqual": false,
|
||||
"ok": false,
|
||||
"PromiseDebugging": false,
|
||||
"runningInParent": false,
|
||||
"run_next_test": false,
|
||||
"run_test": false,
|
||||
|
|
|
@ -169,7 +169,7 @@ module.exports = {
|
|||
"no-trailing-spaces": "error",
|
||||
|
||||
// No using undeclared variables
|
||||
// "no-undef": "error",
|
||||
"no-undef": "error",
|
||||
|
||||
// Error on newline where a semicolon is needed
|
||||
"no-unexpected-multiline": "error",
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
module.exports = {
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
};
|
||||
|
|
|
@ -901,6 +901,43 @@ var insertSyncLivemark = Task.async(function* (insertInfo) {
|
|||
return insertBookmarkMetadata(livemarkItem, insertInfo);
|
||||
});
|
||||
|
||||
// Keywords are a 1 to 1 mapping between strings and pairs of (URL, postData).
|
||||
// (the postData is not synced, so we ignore it). Sync associates keywords with
|
||||
// bookmarks, which is not really accurate. -- We might already have a keyword
|
||||
// with that name, or we might already have another bookmark with that URL with
|
||||
// a different keyword, etc.
|
||||
//
|
||||
// If we don't handle those cases by removing the conflicting keywords first,
|
||||
// the insertion will fail, and the keywords will either be wrong, or missing.
|
||||
// This function handles those cases.
|
||||
var removeConflictingKeywords = Task.async(function* (bookmarkURL, newKeyword) {
|
||||
let entryForURL = yield PlacesUtils.keywords.fetch({
|
||||
url: bookmarkURL
|
||||
});
|
||||
if (entryForURL && entryForURL.keyword !== newKeyword) {
|
||||
yield PlacesUtils.keywords.remove({
|
||||
keyword: entryForURL.keyword,
|
||||
source: SOURCE_SYNC,
|
||||
});
|
||||
// This will cause us to reupload this record for this sync, but without it,
|
||||
// we will risk data corruption.
|
||||
yield BookmarkSyncUtils.addSyncChangesForBookmarksWithURL(entryForURL.url.href);
|
||||
}
|
||||
if (!newKeyword) {
|
||||
return;
|
||||
}
|
||||
let entryForNewKeyword = yield PlacesUtils.keywords.fetch({
|
||||
keyword: newKeyword
|
||||
});
|
||||
if (entryForNewKeyword) {
|
||||
yield PlacesUtils.keywords.remove({
|
||||
keyword: entryForNewKeyword.keyword,
|
||||
source: SOURCE_SYNC,
|
||||
});
|
||||
yield BookmarkSyncUtils.addSyncChangesForBookmarksWithURL(entryForNewKeyword.url.href);
|
||||
}
|
||||
});
|
||||
|
||||
// Sets annotations, keywords, and tags on a new bookmark. Returns a Sync
|
||||
// bookmark object.
|
||||
var insertBookmarkMetadata = Task.async(function* (bookmarkItem, insertInfo) {
|
||||
|
@ -923,6 +960,7 @@ var insertBookmarkMetadata = Task.async(function* (bookmarkItem, insertInfo) {
|
|||
}
|
||||
|
||||
if (insertInfo.keyword) {
|
||||
yield removeConflictingKeywords(bookmarkItem.url.href, insertInfo.keyword);
|
||||
yield PlacesUtils.keywords.insert({
|
||||
keyword: insertInfo.keyword,
|
||||
url: bookmarkItem.url.href,
|
||||
|
@ -1136,15 +1174,7 @@ var updateBookmarkMetadata = Task.async(function* (oldBookmarkItem,
|
|||
|
||||
if (updateInfo.hasOwnProperty("keyword")) {
|
||||
// Unconditionally remove the old keyword.
|
||||
let entry = yield PlacesUtils.keywords.fetch({
|
||||
url: oldBookmarkItem.url.href,
|
||||
});
|
||||
if (entry) {
|
||||
yield PlacesUtils.keywords.remove({
|
||||
keyword: entry.keyword,
|
||||
source: SOURCE_SYNC,
|
||||
});
|
||||
}
|
||||
yield removeConflictingKeywords(oldBookmarkItem.url.href, updateInfo.keyword);
|
||||
if (updateInfo.keyword) {
|
||||
yield PlacesUtils.keywords.insert({
|
||||
keyword: updateInfo.keyword,
|
||||
|
|
|
@ -619,6 +619,98 @@ add_task(function* test_update_keyword() {
|
|||
"Removing keyword for URL without existing keyword should succeed");
|
||||
}
|
||||
|
||||
let item2;
|
||||
do_print("Insert removes other item's keyword if they are the same");
|
||||
{
|
||||
let updatedItem = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item.syncId,
|
||||
keyword: "test",
|
||||
});
|
||||
equal(updatedItem.keyword, "test", "Initial update succeeds");
|
||||
item2 = yield PlacesSyncUtils.bookmarks.insert({
|
||||
kind: "bookmark",
|
||||
parentSyncId: "menu",
|
||||
url: "https://mozilla.org/1",
|
||||
syncId: makeGuid(),
|
||||
keyword: "test",
|
||||
});
|
||||
equal(item2.keyword, "test", "insert with existing should succeed");
|
||||
updatedItem = yield PlacesSyncUtils.bookmarks.fetch(item.syncId);
|
||||
ok(!updatedItem.keyword, "initial item no longer has keyword");
|
||||
let entry = yield PlacesUtils.keywords.fetch({
|
||||
url: "https://mozilla.org",
|
||||
});
|
||||
ok(!entry, "Direct check for original url keyword gives nothing");
|
||||
let newEntry = yield PlacesUtils.keywords.fetch("test");
|
||||
ok(newEntry, "Keyword should exist for new item");
|
||||
equal(newEntry.url.href, "https://mozilla.org/1", "Keyword should point to new url");
|
||||
}
|
||||
|
||||
do_print("Insert updates other item's keyword if they are the same url");
|
||||
{
|
||||
let updatedItem = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item.syncId,
|
||||
keyword: "test2",
|
||||
});
|
||||
equal(updatedItem.keyword, "test2", "Initial update succeeds");
|
||||
let newItem = yield PlacesSyncUtils.bookmarks.insert({
|
||||
kind: "bookmark",
|
||||
parentSyncId: "menu",
|
||||
url: "https://mozilla.org",
|
||||
syncId: makeGuid(),
|
||||
keyword: "test3",
|
||||
});
|
||||
equal(newItem.keyword, "test3", "insert with existing should succeed");
|
||||
updatedItem = yield PlacesSyncUtils.bookmarks.fetch(item.syncId);
|
||||
equal(updatedItem.keyword, "test3", "initial item has new keyword");
|
||||
}
|
||||
|
||||
do_print("Update removes other item's keyword if they are the same");
|
||||
{
|
||||
let updatedItem = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item.syncId,
|
||||
keyword: "test4",
|
||||
});
|
||||
equal(updatedItem.keyword, "test4", "Initial update succeeds");
|
||||
let updatedItem2 = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item2.syncId,
|
||||
keyword: "test4",
|
||||
});
|
||||
equal(updatedItem2.keyword, "test4", "New update succeeds");
|
||||
updatedItem = yield PlacesSyncUtils.bookmarks.fetch(item.syncId);
|
||||
ok(!updatedItem.keyword, "initial item no longer has keyword");
|
||||
let entry = yield PlacesUtils.keywords.fetch({
|
||||
url: "https://mozilla.org",
|
||||
});
|
||||
ok(!entry, "Direct check for original url keyword gives nothing");
|
||||
let newEntry = yield PlacesUtils.keywords.fetch("test4");
|
||||
ok(newEntry, "Keyword should exist for new item");
|
||||
equal(newEntry.url.href, "https://mozilla.org/1", "Keyword should point to new url");
|
||||
}
|
||||
|
||||
do_print("Update url updates it's keyword if url already has keyword");
|
||||
{
|
||||
let updatedItem = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item.syncId,
|
||||
keyword: "test4",
|
||||
});
|
||||
equal(updatedItem.keyword, "test4", "Initial update succeeds");
|
||||
let updatedItem2 = yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item2.syncId,
|
||||
keyword: "test5",
|
||||
});
|
||||
equal(updatedItem2.keyword, "test5", "New update succeeds");
|
||||
yield PlacesSyncUtils.bookmarks.update({
|
||||
syncId: item2.syncId,
|
||||
url: item.url.href,
|
||||
});
|
||||
updatedItem2 = yield PlacesSyncUtils.bookmarks.fetch(item2.syncId);
|
||||
equal(updatedItem2.keyword, "test4", "Item keyword has been updated");
|
||||
updatedItem = yield PlacesSyncUtils.bookmarks.fetch(item.syncId);
|
||||
equal(updatedItem.keyword, "test4", "Initial item still has keyword");
|
||||
}
|
||||
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesSyncUtils.bookmarks.reset();
|
||||
});
|
||||
|
|
|
@ -631,8 +631,11 @@ nsUrlClassifierDBServiceWorker::FinishUpdate()
|
|||
mUpdateStatus : NS_ERROR_UC_UPDATE_UNKNOWN;
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::URLCLASSIFIER_UPDATE_ERROR, provider,
|
||||
NS_ERROR_GET_CODE(updateStatus));
|
||||
// Do not record telemetry for testing tables.
|
||||
if (!provider.Equals(TESTING_TABLE_PROVIDER_NAME)) {
|
||||
Telemetry::Accumulate(Telemetry::URLCLASSIFIER_UPDATE_ERROR, provider,
|
||||
NS_ERROR_GET_CODE(updateStatus));
|
||||
}
|
||||
|
||||
mMissCache.Clear();
|
||||
|
||||
|
@ -989,7 +992,7 @@ nsUrlClassifierLookupCallback::LookupComplete(nsTArray<LookupResult>* results)
|
|||
// has registered the table. In the second case we should not call
|
||||
// complete.
|
||||
if ((!gethashUrl.IsEmpty() ||
|
||||
StringBeginsWith(result.mTableName, NS_LITERAL_CSTRING("test-"))) &&
|
||||
StringBeginsWith(result.mTableName, NS_LITERAL_CSTRING("test"))) &&
|
||||
mDBService->GetCompleter(result.mTableName,
|
||||
getter_AddRefs(completer))) {
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIURLFormatter.h"
|
||||
#include "Classifier.h"
|
||||
|
||||
static const char* gQuitApplicationMessage = "quit-application";
|
||||
|
||||
|
@ -97,6 +98,7 @@ nsUrlClassifierStreamUpdater::DownloadDone()
|
|||
mSuccessCallback = nullptr;
|
||||
mUpdateErrorCallback = nullptr;
|
||||
mDownloadErrorCallback = nullptr;
|
||||
mTelemetryProvider.Truncate();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -283,6 +285,14 @@ nsUrlClassifierStreamUpdater::DownloadUpdates(
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUrlClassifierUtils> urlUtil =
|
||||
do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
|
||||
|
||||
nsTArray<nsCString> tables;
|
||||
mozilla::safebrowsing::Classifier::SplitTables(aRequestTables, tables);
|
||||
urlUtil->GetTelemetryProvider(tables.SafeElementAt(0, EmptyCString()),
|
||||
mTelemetryProvider);
|
||||
|
||||
mSuccessCallback = aSuccessCallback;
|
||||
mUpdateErrorCallback = aUpdateErrorCallback;
|
||||
mDownloadErrorCallback = aDownloadErrorCallback;
|
||||
|
@ -635,17 +645,11 @@ nsUrlClassifierStreamUpdater::OnStartRequest(nsIRequest *request,
|
|||
spec.get(), this));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUrlClassifierUtils> urlUtil =
|
||||
do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
|
||||
|
||||
nsCString provider;
|
||||
urlUtil->GetTelemetryProvider(mStreamTable, provider);
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
// Assume we're overloading the server and trigger backoff.
|
||||
downloadError = true;
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::URLCLASSIFIER_UPDATE_REMOTE_STATUS2,
|
||||
provider, 15 /* unknown response code */);
|
||||
mTelemetryProvider, 15 /* unknown response code */);
|
||||
|
||||
} else {
|
||||
bool succeeded = false;
|
||||
|
@ -656,7 +660,7 @@ nsUrlClassifierStreamUpdater::OnStartRequest(nsIRequest *request,
|
|||
rv = httpChannel->GetResponseStatus(&requestStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::URLCLASSIFIER_UPDATE_REMOTE_STATUS2,
|
||||
provider, HTTPStatusToBucket(requestStatus));
|
||||
mTelemetryProvider, HTTPStatusToBucket(requestStatus));
|
||||
LOG(("nsUrlClassifierStreamUpdater::OnStartRequest %s (%d)", succeeded ?
|
||||
"succeeded" : "failed", requestStatus));
|
||||
if (!succeeded) {
|
||||
|
|
|
@ -73,7 +73,10 @@ private:
|
|||
bool mInitialized;
|
||||
bool mDownloadError;
|
||||
bool mBeganStream;
|
||||
|
||||
// Note that mStreamTable is only used by v2, it is empty for v4 update.
|
||||
nsCString mStreamTable;
|
||||
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsIUrlClassifierDBService> mDBService;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
@ -98,6 +101,10 @@ private:
|
|||
nsCOMPtr<nsIUrlClassifierCallback> mSuccessCallback;
|
||||
nsCOMPtr<nsIUrlClassifierCallback> mUpdateErrorCallback;
|
||||
nsCOMPtr<nsIUrlClassifierCallback> mDownloadErrorCallback;
|
||||
|
||||
// The provider for current update request and should be only used by telemetry
|
||||
// since it would show up as "other" for any other providers.
|
||||
nsCString mTelemetryProvider;
|
||||
};
|
||||
|
||||
#endif // nsUrlClassifierStreamUpdater_h_
|
||||
|
|
|
@ -279,7 +279,9 @@ nsUrlClassifierUtils::GetProvider(const nsACString& aTableName,
|
|||
{
|
||||
MutexAutoLock lock(mProviderDictLock);
|
||||
nsCString* provider = nullptr;
|
||||
if (mProviderDict.Get(aTableName, &provider)) {
|
||||
if (StringBeginsWith(aTableName, NS_LITERAL_CSTRING("test"))) {
|
||||
aProvider = NS_LITERAL_CSTRING(TESTING_TABLE_PROVIDER_NAME);
|
||||
} else if (mProviderDict.Get(aTableName, &provider)) {
|
||||
aProvider = provider ? *provider : EmptyCString();
|
||||
} else {
|
||||
aProvider = EmptyCString();
|
||||
|
@ -296,7 +298,8 @@ nsUrlClassifierUtils::GetTelemetryProvider(const nsACString& aTableName,
|
|||
// Empty provider is filtered as "other"
|
||||
if (!NS_LITERAL_CSTRING("mozilla").Equals(aProvider) &&
|
||||
!NS_LITERAL_CSTRING("google").Equals(aProvider) &&
|
||||
!NS_LITERAL_CSTRING("google4").Equals(aProvider)) {
|
||||
!NS_LITERAL_CSTRING("google4").Equals(aProvider) &&
|
||||
!NS_LITERAL_CSTRING(TESTING_TABLE_PROVIDER_NAME).Equals(aProvider)) {
|
||||
aProvider.Assign(NS_LITERAL_CSTRING("other"));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "nsClassHashtable.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#define TESTING_TABLE_PROVIDER_NAME "test"
|
||||
|
||||
class nsUrlClassifierUtils final : public nsIUrlClassifierUtils,
|
||||
public nsIObserver
|
||||
{
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
/* import-globals-from crasher_subprocess_head.js */
|
||||
|
||||
// Let the event loop process a bit before crashing.
|
||||
if (shouldDelay) {
|
||||
let shouldCrashNow = false;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
function run_test() {
|
||||
do_crash(function() {
|
||||
appAddr = CrashTestUtils.saveAppMemory();
|
||||
crashReporter.registerAppMemory(appAddr, 32);
|
||||
},
|
||||
function(mdump, extra) {
|
||||
do_check_true(mdump.exists());
|
||||
do_check_true(mdump.fileSize > 0);
|
||||
do_check_true(CrashTestUtils.dumpCheckMemory(mdump.path));
|
||||
});
|
||||
let appAddr = CrashTestUtils.saveAppMemory();
|
||||
crashReporter.registerAppMemory(appAddr, 32);
|
||||
},
|
||||
function(mdump, extra) {
|
||||
do_check_true(mdump.exists());
|
||||
do_check_true(mdump.fileSize > 0);
|
||||
do_check_true(CrashTestUtils.dumpCheckMemory(mdump.path));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -138,6 +138,7 @@ GMPInstallManager.prototype = {
|
|||
*/
|
||||
installAddon(gmpAddon) {
|
||||
if (this._deferred) {
|
||||
let log = getScopedLogger("GMPInstallManager.installAddon");
|
||||
log.error("previous error encountered");
|
||||
return Promise.reject({type: "previouserrorencountered"});
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
|
||||
var pSlice = Array.prototype.slice;
|
||||
|
||||
this.ObjectUtils = {
|
||||
/**
|
||||
* This tests objects & values for deep equality.
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
// that Components is not defined in worker threads, so no instance of Cu can
|
||||
// be obtained.
|
||||
|
||||
// As this can be loaded in several ways, allow require and module to be defined.
|
||||
/* global module:false require:false */
|
||||
// This is allowed in workers.
|
||||
/* global setImmediate:false */
|
||||
|
||||
var Cu = this.require ? require("chrome").Cu : Components.utils;
|
||||
var Cc = this.require ? require("chrome").Cc : Components.classes;
|
||||
var Ci = this.require ? require("chrome").Ci : Components.interfaces;
|
||||
|
|
|
@ -57,13 +57,13 @@ function saveStreamAsync(aPath, aStream, aFile) {
|
|||
try {
|
||||
aStream.close();
|
||||
} catch (e) {
|
||||
logger.error("Failed to close JAR stream for " + aPath);
|
||||
Cu.reportError("Failed to close JAR stream for " + aPath);
|
||||
}
|
||||
|
||||
aFile.close().then(function() {
|
||||
deferred.reject(error);
|
||||
}, function(e) {
|
||||
logger.error("Failed to close file for " + aPath);
|
||||
Cu.reportError("Failed to close file for " + aPath);
|
||||
deferred.reject(error);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
|
|||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome/chrome.ini']
|
||||
|
||||
TESTING_JS_MODULES += [
|
||||
'tests/MockDocument.jsm',
|
||||
'tests/PromiseTestUtils.jsm',
|
||||
'tests/modules/MockDocument.jsm',
|
||||
'tests/modules/PromiseTestUtils.jsm',
|
||||
'tests/xpcshell/TestIntegration.jsm',
|
||||
]
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
var InlineSpellChecker;
|
||||
|
||||
function test() {
|
||||
let tempScope = {};
|
||||
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm", tempScope);
|
||||
let InlineSpellChecker = tempScope.InlineSpellChecker;
|
||||
InlineSpellChecker = tempScope.InlineSpellChecker;
|
||||
|
||||
ok(InlineSpellChecker, "InlineSpellChecker class exists");
|
||||
for (var fname in tests) {
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
/* global addMessageListener, sendAsyncMessage, removeMessageListener */
|
||||
|
||||
addMessageListener("Ping", function(message) {
|
||||
sendAsyncMessage("Pong", {
|
||||
str: message.data.str,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
|
@ -6,6 +6,9 @@
|
|||
* will fail tests in this case, unless the test whitelists itself.
|
||||
*/
|
||||
|
||||
// For this test we allow the global Assert to be modified.
|
||||
/* global Assert:true */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
|
@ -101,4 +101,13 @@ add_task(function* test_deepEqual() {
|
|||
} catch (e) {
|
||||
Assert.ok(true, "Didn't recurse infinitely.");
|
||||
}
|
||||
|
||||
let e = {a: 3, b: 4};
|
||||
let f = {b: 4, a: 3};
|
||||
|
||||
function checkEquiv() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
Assert.ok(deepEqual(checkEquiv(e, f), checkEquiv(f, e)));
|
||||
});
|
||||
|
|
|
@ -850,7 +850,6 @@ add_task(function* test_direct() {
|
|||
print("Error when executing SQL (" + error.result + "): " +
|
||||
error.message);
|
||||
print("Original error: " + error.error);
|
||||
errors.push(error);
|
||||
deferred.reject();
|
||||
},
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
* are identical to their original files.
|
||||
*/
|
||||
|
||||
// Available to the js shell.
|
||||
/* global snarf, scriptArgs, quit */
|
||||
|
||||
"use strict";
|
||||
|
||||
function ast(filename) {
|
||||
|
|
|
@ -65,15 +65,33 @@ const globalCache = new Map();
|
|||
* parents parameter which is a list of the parent nodes of the current node.
|
||||
* Each returns an array of globals found.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String} filePath
|
||||
* The absolute path of the file being parsed.
|
||||
*/
|
||||
function GlobalsForNode(path) {
|
||||
this.path = path;
|
||||
this.root = helpers.getRootDir(path);
|
||||
function GlobalsForNode(filePath) {
|
||||
this.path = filePath;
|
||||
this.dirname = path.dirname(this.path)
|
||||
this.root = helpers.getRootDir(this.path);
|
||||
this.isWorker = helpers.getIsWorker(this.path);
|
||||
}
|
||||
|
||||
GlobalsForNode.prototype = {
|
||||
Program(node) {
|
||||
if (!this.isWorker) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{name: "importScripts", writable: false},
|
||||
// Only available to workers.
|
||||
{name: "FileReaderSync", writable: false},
|
||||
{name: "onmessage", writable: true},
|
||||
// Only available to chrome workers, but since we don't know which is which,
|
||||
// we make it available anyway.
|
||||
{name: "ctypes", writable: false}
|
||||
];
|
||||
},
|
||||
|
||||
BlockComment(node, parents) {
|
||||
let value = node.value.trim();
|
||||
let match = /^import-globals-from\s+(.+)$/.exec(value);
|
||||
|
@ -84,8 +102,7 @@ GlobalsForNode.prototype = {
|
|||
let filePath = match[1].trim();
|
||||
|
||||
if (!path.isAbsolute(filePath)) {
|
||||
let dirName = path.dirname(this.path);
|
||||
filePath = path.resolve(dirName, filePath);
|
||||
filePath = path.resolve(this.dirname, filePath);
|
||||
}
|
||||
|
||||
return module.exports.getGlobalsForFile(filePath);
|
||||
|
@ -93,8 +110,19 @@ GlobalsForNode.prototype = {
|
|||
|
||||
ExpressionStatement(node, parents) {
|
||||
let isGlobal = helpers.getIsGlobalScope(parents);
|
||||
let names = helpers.convertExpressionToGlobals(node, isGlobal, this.root);
|
||||
return names.map(name => { return { name, writable: true }});
|
||||
let globals = helpers.convertExpressionToGlobals(node, isGlobal, this.root);
|
||||
// Map these globals now, as getGlobalsForFile is pre-mapped.
|
||||
globals = globals.map(name => { return { name, writable: true }});
|
||||
|
||||
if (this.isWorker) {
|
||||
let workerDetails = helpers.convertWorkerExpressionToGlobals(node,
|
||||
isGlobal, this.root, this.dirname);
|
||||
globals = globals.concat(workerDetails.map(name => {
|
||||
return { name, writable: true };
|
||||
}));
|
||||
}
|
||||
|
||||
return globals;
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -106,6 +134,12 @@ module.exports = {
|
|||
*
|
||||
* @param {String} path
|
||||
* The absolute path of the file to be parsed.
|
||||
* @return {Array}
|
||||
* An array of objects that contain details about the globals:
|
||||
* - {String} name
|
||||
* The name of the global.
|
||||
* - {Boolean} writable
|
||||
* If the global is writeable or not.
|
||||
*/
|
||||
getGlobalsForFile(path) {
|
||||
if (globalCache.has(path)) {
|
||||
|
@ -179,6 +213,9 @@ module.exports = {
|
|||
|
||||
for (let type of Object.keys(GlobalsForNode.prototype)) {
|
||||
parser[type] = function(node) {
|
||||
if (type === "Program") {
|
||||
globalScope = context.getScope();
|
||||
}
|
||||
let globals = handler[type](node, context.getAncestors());
|
||||
helpers.addGlobals(globals, globalScope);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ var imports = [
|
|||
/^(?:Cu|Components\.utils)\.import\(".*\/((.*?)\.jsm?)"(?:, this)?\)/,
|
||||
];
|
||||
|
||||
var workerImportFilenameMatch = /(.*\/)*(.*?\.jsm?)/;
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Gets the abstract syntax tree (AST) of the JavaScript source code contained
|
||||
|
@ -168,8 +170,40 @@ module.exports = {
|
|||
* The root of the repository.
|
||||
*
|
||||
* @return {Array}
|
||||
* An array of variable names defined.
|
||||
* An array of global variable names defined.
|
||||
*/
|
||||
convertWorkerExpressionToGlobals: function(node, isGlobal, repository, dirname) {
|
||||
var getGlobalsForFile = require("./globals").getGlobalsForFile;
|
||||
|
||||
if (!modules) {
|
||||
modules = require(path.join(repository, "tools", "lint", "eslint", "modules.json"));
|
||||
}
|
||||
|
||||
let results = [];
|
||||
let expr = node.expression;
|
||||
|
||||
if (node.expression.type === "CallExpression" &&
|
||||
expr.callee &&
|
||||
expr.callee.type === "Identifier" &&
|
||||
expr.callee.name === "importScripts") {
|
||||
for (var arg of expr.arguments) {
|
||||
var match = arg.value.match(workerImportFilenameMatch);
|
||||
if (match) {
|
||||
if (!match[1]) {
|
||||
let filePath = path.resolve(dirname, match[2]);
|
||||
if (fs.existsSync(filePath)) {
|
||||
let additionalGlobals = getGlobalsForFile(filePath);
|
||||
results = results.concat(additionalGlobals);
|
||||
}
|
||||
} else if (match[2] in modules) {
|
||||
results.push(modules[match[2]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
convertExpressionToGlobals: function(node, isGlobal, repository) {
|
||||
if (!modules) {
|
||||
modules = require(path.join(repository, "tools", "lint", "eslint", "modules.json"));
|
||||
|
@ -460,6 +494,12 @@ module.exports = {
|
|||
return null;
|
||||
},
|
||||
|
||||
getIsWorker: function(filePath) {
|
||||
let filename = path.basename(this.cleanUpPath(filePath)).toLowerCase();
|
||||
|
||||
return filename.includes("worker");
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the root directory of the repository by walking up directories until
|
||||
* a .eslintignore file is found.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "eslint-plugin-mozilla",
|
||||
"version": "0.2.16",
|
||||
"version": "0.2.17",
|
||||
"description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
"EventUtils.js": ["disableNonTestMouseEvents", "sendMouseEvent", "sendChar", "sendString", "sendKey", "synthesizeMouse", "synthesizeTouch", "synthesizeMouseAtPoint", "synthesizeTouchAtPoint", "synthesizeMouseAtCenter", "synthesizeTouchAtCenter", "synthesizeWheel", "synthesizeKey", "synthesizeMouseExpectEvent", "synthesizeKeyExpectEvent", "synthesizeText", "synthesizeComposition", "synthesizeQuerySelectedText"],
|
||||
"Extension.jsm": ["Extension", "ExtensionData"],
|
||||
"ExtensionAPI.jsm": ["ExtensionAPI", "ExtensionAPIs"],
|
||||
"ExtensionsUI.jsm": ["ExtensionsUI"],
|
||||
"extension-storage.js": ["ExtensionStorageEngine", "EncryptionRemoteTransformer", "KeyRingEncryptionRemoteTransformer"],
|
||||
"ExtensionXPCShellUtils.jsm": ["ExtensionTestUtils"],
|
||||
"fakeservices.js": ["FakeCryptoService", "FakeFilesystemService", "FakeGUIDService", "fakeSHA256HMAC"],
|
||||
|
@ -110,6 +111,7 @@
|
|||
"import_sub_module.jsm": ["SUBMODULE_IMPORTED", "test_obj"],
|
||||
"InlineSpellChecker.jsm": ["InlineSpellChecker", "SpellCheckHelper"],
|
||||
"JNI.jsm": ["JNI", "android_log"],
|
||||
"JSDOMParser.js": ["JSDOMParser"],
|
||||
"Jsbeautify.jsm": ["jsBeautify"],
|
||||
"jsdebugger.jsm": ["addDebuggerToGlobal"],
|
||||
"json2.js": ["JSON"],
|
||||
|
@ -149,7 +151,7 @@
|
|||
"offlineAppCache.jsm": ["OfflineAppCacheHelper"],
|
||||
"OrientationChangeHandler.jsm": [],
|
||||
"os.js": ["listDirectory", "getFileForPath", "abspath", "getPlatform"],
|
||||
"osfile.jsm": ["OS"],
|
||||
"osfile.jsm": ["OS", "require"],
|
||||
"osfile_async_front.jsm": ["OS"],
|
||||
"osfile_native.jsm": ["read"],
|
||||
"osfile_shared_allthreads.jsm": ["LOG", "clone", "Config", "Constants", "Type", "HollowStructure", "OSError", "Library", "declareFFI", "declareLazy", "declareLazyFFI", "normalizeBufferArgs", "projectValue", "isArrayBuffer", "isTypedArray", "defineLazyGetter", "OS"],
|
||||
|
@ -176,6 +178,7 @@
|
|||
"PromiseWorker.jsm": ["BasePromiseWorker"],
|
||||
"PushCrypto.jsm": ["PushCrypto", "concatArray"],
|
||||
"quit.js": ["goQuitApplication"],
|
||||
"Readability.js": ["Readability"],
|
||||
"record.js": ["WBORecord", "RecordManager", "CryptoWrapper", "CollectionKeyManager", "Collection"],
|
||||
"recursive_importA.jsm": ["foo", "bar"],
|
||||
"recursive_importB.jsm": ["baz", "qux"],
|
||||
|
@ -187,6 +190,7 @@
|
|||
"responsivedesign.jsm": ["ResponsiveUIManager"],
|
||||
"rest.js": ["RESTRequest", "RESTResponse", "TokenAuthenticatedRESTRequest", "SyncStorageRequest"],
|
||||
"rotaryengine.js": ["RotaryEngine", "RotaryRecord", "RotaryStore", "RotaryTracker"],
|
||||
"require.js": ["require"],
|
||||
"RTCStatsReport.jsm": ["convertToRTCStatsReport"],
|
||||
"scratchpad-manager.jsm": ["ScratchpadManager"],
|
||||
"server.js": ["MarionetteServer"],
|
||||
|
|
Загрузка…
Ссылка в новой задаче