diff --git a/.eslintignore b/.eslintignore index dd0755fe7b68..9d88af95941b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -22,7 +22,6 @@ extensions/spellcheck/** extensions/universalchardet/** image/** layout/** -modules/** netwerk/cookie/test/browser/** netwerk/test/browser/** netwerk/test/mochitests/** diff --git a/accessible/base/RoleMap.h b/accessible/base/RoleMap.h index aab5c92c19fb..5e5d79146e5f 100644 --- a/accessible/base/RoleMap.h +++ b/accessible/base/RoleMap.h @@ -958,7 +958,7 @@ ROLE(NON_NATIVE_DOCUMENT, "non-native document", ATK_ROLE_DOCUMENT_FRAME, NSAccessibilityGroupRole, - USE_ROLE_STRING, + ROLE_SYSTEM_DOCUMENT, ROLE_SYSTEM_DOCUMENT, java::SessionAccessibility::CLASSNAME_VIEW, eNoNameRule) diff --git a/accessible/windows/msaa/DocAccessibleWrap.cpp b/accessible/windows/msaa/DocAccessibleWrap.cpp index 62448f6bbdf9..6c3fcfcd0696 100644 --- a/accessible/windows/msaa/DocAccessibleWrap.cpp +++ b/accessible/windows/msaa/DocAccessibleWrap.cpp @@ -77,7 +77,8 @@ DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) { // If document is being used to create a widget, don't use the URL hack roles::Role role = Role(); if (role != roles::DOCUMENT && role != roles::APPLICATION && - role != roles::DIALOG && role != roles::ALERT) + role != roles::DIALOG && role != roles::ALERT && + role != roles::NON_NATIVE_DOCUMENT) return hr; nsAutoString url; diff --git a/browser/modules/Sanitizer.jsm b/browser/modules/Sanitizer.jsm index d4c6d9415076..a336ed94a37d 100644 --- a/browser/modules/Sanitizer.jsm +++ b/browser/modules/Sanitizer.jsm @@ -674,6 +674,10 @@ async function sanitizeOnShutdown(progress) { await Sanitizer.sanitize(itemsToClear, { progress }); } + // Here is the list of principals with site data. + progress.advancement = "get-principals"; + let principals = await getAllPrincipals(progress); + // Clear out QuotaManager storage for principals that have been marked as // session only. The cookie service has special logic that avoids writing // such cookies to disk, but QuotaManager always touches disk, so we need to @@ -700,8 +704,8 @@ async function sanitizeOnShutdown(progress) { Ci.nsICookieService.ACCEPT_NORMALLY) == Ci.nsICookieService.ACCEPT_SESSION) { log("Session-only configuration detected"); progress.advancement = "session-only"; - let principals = await getAllPrincipals(progress); await maybeSanitizeSessionPrincipals(progress, principals); + return; } progress.advancement = "session-permission"; @@ -721,8 +725,8 @@ async function sanitizeOnShutdown(progress) { log("Custom session cookie permission detected for: " + permission.principal.URI.spec); // We use just the URI here, because permissions ignore OriginAttributes. - let principals = await getAllPrincipals(progress, permission.principal.URI); - await maybeSanitizeSessionPrincipals(progress, principals); + let selectedPrincipals = extractMatchingPrincipals(principals, permission.principal.URI); + await maybeSanitizeSessionPrincipals(progress, selectedPrincipals); } if (Sanitizer.shouldSanitizeNewTabContainer) { @@ -741,10 +745,8 @@ async function sanitizeOnShutdown(progress) { progress.advancement = "done"; } -// Retrieve the list of nsIPrincipals with site data. If matchUri is not null, -// it returns only the principals matching that URI, ignoring the -// OriginAttributes. -async function getAllPrincipals(progress, matchUri = null) { +// Retrieve the list of nsIPrincipals with site data. +async function getAllPrincipals(progress) { progress.step = "principals-quota-manager"; let principals = await new Promise(resolve => { quotaManagerService.getUsage(request => { @@ -759,11 +761,7 @@ async function getAllPrincipals(progress, matchUri = null) { for (let item of request.result) { let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(item.origin); let uri = principal.URI; - if (!isSupportedURI(uri)) { - continue; - } - - if (!matchUri || Services.eTLD.hasRootDomain(matchUri.host, uri.host)) { + if (isSupportedURI(uri)) { list.push(principal); } } @@ -775,11 +773,8 @@ async function getAllPrincipals(progress, matchUri = null) { let serviceWorkers = serviceWorkerManager.getAllRegistrations(); for (let i = 0; i < serviceWorkers.length; i++) { let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo); - let uri = sw.principal.URI; // We don't need to check the scheme. SW are just exposed to http/https URLs. - if (!matchUri || Services.eTLD.hasRootDomain(matchUri.host, uri.host)) { - principals.push(sw.principal); - } + principals.push(sw.principal); } // Let's take the list of unique hosts+OA from cookies. @@ -787,9 +782,7 @@ async function getAllPrincipals(progress, matchUri = null) { let enumerator = Services.cookies.enumerator; let hosts = new Set(); for (let cookie of enumerator) { - if (!matchUri || Services.eTLD.hasRootDomain(matchUri.host, cookie.rawHost)) { - hosts.add(cookie.rawHost + ChromeUtils.originAttributesToSuffix(cookie.originAttributes)); - } + hosts.add(cookie.rawHost + ChromeUtils.originAttributesToSuffix(cookie.originAttributes)); } progress.step = "principals-host-cookie"; @@ -804,6 +797,13 @@ async function getAllPrincipals(progress, matchUri = null) { return principals; } +// Extracts the principals matching matchUri as root domain. +function extractMatchingPrincipals(principals, matchUri) { + return principals.filter(principal => { + return Services.eTLD.hasRootDomain(matchUri.host, principal.URI.host); + }); +} + // This method receives a list of principals and it checks if some of them or // some of their sub-domain need to be sanitize. async function maybeSanitizeSessionPrincipals(progress, principals) { diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index e60cfad6d0ef..0a899e17d882 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -3190,13 +3190,11 @@ nsresult Selection::NotifySelectionListeners() { if (newEditingHost && newEditingHost != focusedElement) { MOZ_ASSERT(!newEditingHost->IsInNativeAnonymousSubtree()); // Note that don't steal focus from focused window if the window doesn't - // have focus and if the window isn't focused window, shouldn't be - // scrolled to the new focused element. - uint32_t flags = nsIFocusManager::FLAG_NOSWITCHFRAME; - if (focusedWindow != fm->GetFocusedWindow()) { - flags |= nsIFocusManager::FLAG_NOSCROLL; - } - fm->SetFocus(newEditingHost, flags); + // have focus. Additionally, although when an element gets focus, we + // usually scroll to the element, but in this case, we shouldn't do it + // because Chrome does not do so. + fm->SetFocus(newEditingHost, nsIFocusManager::FLAG_NOSWITCHFRAME | + nsIFocusManager::FLAG_NOSCROLL); } } } diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index b0123e9919ff..dd687d512f4b 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -5733,6 +5733,13 @@ bool CanvasRenderingContext2D::ShouldForceInactiveLayer( return !aManager->CanUseCanvasLayerForSize(GetSize()); } +void CanvasRenderingContext2D::SetWriteOnly() { + mWriteOnly = true; + if (mCanvasElement) { + mCanvasElement->SetWriteOnly(); + } +} + NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release) diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index a7b9c99b1b24..057aedcb929f 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -1114,7 +1114,7 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal, friend class CanvasDrawObserver; friend class ImageBitmap; - void SetWriteOnly() { mWriteOnly = true; } + void SetWriteOnly(); bool IsWriteOnly() const { return mWriteOnly; } diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index b515c0647f67..415751c5d755 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -1283,7 +1283,7 @@ tags = suspend skip-if = toolkit == 'android' # bug 1346705 tags = suspend [test_background_video_resume_after_end_show_last_frame.html] -skip-if = toolkit == 'android' # bug 1346705 +skip-if = toolkit == 'android' || ( webrender && os == "linux") # bug 1346705, bug 1516043 tags = suspend [test_background_video_suspend.html] skip-if = toolkit == 'android' # android(bug 1304480) diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp index 5a33b47cb14d..cbb037b4c898 100644 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -1198,6 +1198,13 @@ void AudioContext::Unmute() const { } } +void AudioContext::SetParamMapForWorkletName( + const nsAString& aName, AudioParamDescriptorMap* aParamMap) { + MOZ_ASSERT(!mWorkletParamDescriptors.GetValue(aName)); + Unused << mWorkletParamDescriptors.Put(aName, std::move(*aParamMap), + fallible); +} + size_t AudioContext::SizeOfIncludingThis( mozilla::MallocSizeOf aMallocSizeOf) const { // AudioNodes are tracked separately because we do not want the AudioContext diff --git a/dom/media/webaudio/AudioContext.h b/dom/media/webaudio/AudioContext.h index 16bda77246ee..7656dc7046e3 100644 --- a/dom/media/webaudio/AudioContext.h +++ b/dom/media/webaudio/AudioContext.h @@ -7,6 +7,7 @@ #ifndef AudioContext_h_ #define AudioContext_h_ +#include "AudioParamDescriptorMap.h" #include "mozilla/dom/OfflineAudioContextBinding.h" #include "MediaBufferDecoder.h" #include "mozilla/Attributes.h" @@ -311,6 +312,14 @@ class AudioContext final : public DOMEventTargetHelper, bool CheckClosed(ErrorResult& aRv); + // Steals from |aParamMap| + void SetParamMapForWorkletName(const nsAString& aName, + AudioParamDescriptorMap* aParamMap); + const AudioParamDescriptorMap* GetParamMapForWorkletName( + const nsAString& aName) { + return mWorkletParamDescriptors.GetValue(aName); + } + void Dispatch(already_AddRefed&& aRunnable); private: @@ -371,6 +380,8 @@ class AudioContext final : public DOMEventTargetHelper, nsTHashtable> mActiveNodes; // Raw (non-owning) references to all AudioNodes for this AudioContext. nsTHashtable> mAllNodes; + nsDataHashtable + mWorkletParamDescriptors; // Cache to avoid recomputing basic waveforms all the time. RefPtr mBasicWaveFormCache; // Number of channels passed in the OfflineAudioContext ctor. diff --git a/dom/media/webaudio/AudioWorkletGlobalScope.cpp b/dom/media/webaudio/AudioWorkletGlobalScope.cpp index 3ebcf9173a40..3a797538aaf7 100644 --- a/dom/media/webaudio/AudioWorkletGlobalScope.cpp +++ b/dom/media/webaudio/AudioWorkletGlobalScope.cpp @@ -6,6 +6,8 @@ #include "AudioWorkletGlobalScope.h" +#include "AudioNodeEngine.h" +#include "AudioNodeStream.h" #include "AudioWorkletImpl.h" #include "jsapi.h" #include "mozilla/dom/AudioWorkletGlobalScopeBinding.h" @@ -186,10 +188,17 @@ void AudioWorkletGlobalScope::RegisterProcessor(JSContext* aCx, if (aRv.Failed()) { return; } - // TODO: we don't have a proper mechanism to communicate with the - // control thread currently. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=1473467#c3 - // and https://bugzilla.mozilla.org/show_bug.cgi?id=1492014 + + NS_DispatchToMainThread(NS_NewRunnableFunction( + "AudioWorkletGlobalScope: parameter descriptors", + [impl = mImpl, name = nsString(aName), map = std::move(map)]() mutable { + AudioNode* destinationNode = + impl->DestinationStream()->Engine()->NodeMainThread(); + if (!destinationNode) { + return; + } + destinationNode->Context()->SetParamMapForWorkletName(name, &map); + })); } WorkletImpl* AudioWorkletGlobalScope::Impl() const { return mImpl; } diff --git a/dom/media/webaudio/AudioWorkletImpl.h b/dom/media/webaudio/AudioWorkletImpl.h index 6273d6cd4401..e6544c386e5f 100644 --- a/dom/media/webaudio/AudioWorkletImpl.h +++ b/dom/media/webaudio/AudioWorkletImpl.h @@ -29,6 +29,9 @@ class AudioWorkletImpl final : public WorkletImpl { nsresult SendControlMessage(already_AddRefed aRunnable) override; + // Any thread: + AudioNodeStream* DestinationStream() { return mDestinationStream; } + protected: // Execution thread only. already_AddRefed ConstructGlobalScope() override; diff --git a/dom/media/webaudio/AudioWorkletNode.cpp b/dom/media/webaudio/AudioWorkletNode.cpp index 05df5c0dd8e7..0011f82869bb 100644 --- a/dom/media/webaudio/AudioWorkletNode.cpp +++ b/dom/media/webaudio/AudioWorkletNode.cpp @@ -48,6 +48,17 @@ AudioWorkletNode::AudioWorkletNode(AudioContext* aAudioContext, } } } + /** + * 2. If nodeName does not exists as a key in the BaseAudioContext’s node + * name to parameter descriptor map, throw a NotSupportedError exception + * and abort these steps. + */ + const AudioParamDescriptorMap* parameterDescriptors = + aAudioContext.GetParamMapForWorkletName(aName); + if (!parameterDescriptors) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; + } RefPtr audioWorkletNode = new AudioWorkletNode(&aAudioContext, aName); diff --git a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp index 84d3b89f74de..894c8d613442 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp @@ -267,7 +267,7 @@ public: cairo_font_face_t* GetCairoFontFace() const { return fFontFace; } -private: + private: ~SkCairoFTTypeface() { cairo_font_face_destroy(fFontFace); @@ -283,7 +283,8 @@ private: }; static bool FindByCairoFontFace(SkTypeface* typeface, void* context) { - return static_cast(typeface)->GetCairoFontFace() == static_cast(context); + return static_cast(typeface)->GetCairoFontFace() == + static_cast(context); } SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern) @@ -292,10 +293,11 @@ SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* s SkASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS); SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT); - SkTypeface* typeface = SkTypefaceCache::FindByProcAndRef(FindByCairoFontFace, fontFace); + SkTypeface* typeface = + SkTypefaceCache::FindByProcAndRef(FindByCairoFontFace, fontFace); if (!typeface) { - typeface = new SkCairoFTTypeface(fontFace, pattern); - SkTypefaceCache::Add(typeface); + typeface = new SkCairoFTTypeface(fontFace, pattern); + SkTypefaceCache::Add(typeface); } return typeface; diff --git a/intl/l10n/FluentSyntax.jsm b/intl/l10n/FluentSyntax.jsm new file mode 100644 index 000000000000..28c349e4af99 --- /dev/null +++ b/intl/l10n/FluentSyntax.jsm @@ -0,0 +1,1930 @@ +/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ + +/* Copyright 2019 Mozilla Foundation and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* fluent-syntax@0.10.0 */ + +/* + * Base class for all Fluent AST nodes. + * + * All productions described in the ASDL subclass BaseNode, including Span and + * Annotation. + * + */ +class BaseNode { + constructor() {} +} + +/* + * Base class for AST nodes which can have Spans. + */ +class SyntaxNode extends BaseNode { + addSpan(start, end) { + this.span = new Span(start, end); + } +} + +class Resource extends SyntaxNode { + constructor(body = []) { + super(); + this.type = "Resource"; + this.body = body; + } +} + +/* + * An abstract base class for useful elements of Resource.body. + */ +class Entry extends SyntaxNode {} + +class Message extends Entry { + constructor(id, value = null, attributes = [], comment = null) { + super(); + this.type = "Message"; + this.id = id; + this.value = value; + this.attributes = attributes; + this.comment = comment; + } +} + +class Term extends Entry { + constructor(id, value, attributes = [], comment = null) { + super(); + this.type = "Term"; + this.id = id; + this.value = value; + this.attributes = attributes; + this.comment = comment; + } +} + +class VariantList extends SyntaxNode { + constructor(variants) { + super(); + this.type = "VariantList"; + this.variants = variants; + } +} + +class Pattern extends SyntaxNode { + constructor(elements) { + super(); + this.type = "Pattern"; + this.elements = elements; + } +} + +/* + * An abstract base class for elements of Patterns. + */ +class PatternElement extends SyntaxNode {} + +class TextElement extends PatternElement { + constructor(value) { + super(); + this.type = "TextElement"; + this.value = value; + } +} + +class Placeable extends PatternElement { + constructor(expression) { + super(); + this.type = "Placeable"; + this.expression = expression; + } +} + +/* + * An abstract base class for expressions. + */ +class Expression extends SyntaxNode {} + +class StringLiteral extends Expression { + constructor(raw, value) { + super(); + this.type = "StringLiteral"; + this.raw = raw; + this.value = value; + } +} + +class NumberLiteral extends Expression { + constructor(value) { + super(); + this.type = "NumberLiteral"; + this.value = value; + } +} + +class MessageReference extends Expression { + constructor(id) { + super(); + this.type = "MessageReference"; + this.id = id; + } +} + +class TermReference extends Expression { + constructor(id) { + super(); + this.type = "TermReference"; + this.id = id; + } +} + +class VariableReference extends Expression { + constructor(id) { + super(); + this.type = "VariableReference"; + this.id = id; + } +} + +class FunctionReference extends Expression { + constructor(id) { + super(); + this.type = "FunctionReference"; + this.id = id; + } +} + +class SelectExpression extends Expression { + constructor(selector, variants) { + super(); + this.type = "SelectExpression"; + this.selector = selector; + this.variants = variants; + } +} + +class AttributeExpression extends Expression { + constructor(ref, name) { + super(); + this.type = "AttributeExpression"; + this.ref = ref; + this.name = name; + } +} + +class VariantExpression extends Expression { + constructor(ref, key) { + super(); + this.type = "VariantExpression"; + this.ref = ref; + this.key = key; + } +} + +class CallExpression extends Expression { + constructor(callee, positional = [], named = []) { + super(); + this.type = "CallExpression"; + this.callee = callee; + this.positional = positional; + this.named = named; + } +} + +class Attribute extends SyntaxNode { + constructor(id, value) { + super(); + this.type = "Attribute"; + this.id = id; + this.value = value; + } +} + +class Variant extends SyntaxNode { + constructor(key, value, def = false) { + super(); + this.type = "Variant"; + this.key = key; + this.value = value; + this.default = def; + } +} + +class NamedArgument extends SyntaxNode { + constructor(name, value) { + super(); + this.type = "NamedArgument"; + this.name = name; + this.value = value; + } +} + +class Identifier extends SyntaxNode { + constructor(name) { + super(); + this.type = "Identifier"; + this.name = name; + } +} + +class BaseComment extends Entry { + constructor(content) { + super(); + this.type = "BaseComment"; + this.content = content; + } +} + +class Comment extends BaseComment { + constructor(content) { + super(content); + this.type = "Comment"; + } +} + +class GroupComment extends BaseComment { + constructor(content) { + super(content); + this.type = "GroupComment"; + } +} +class ResourceComment extends BaseComment { + constructor(content) { + super(content); + this.type = "ResourceComment"; + } +} + +class Junk extends SyntaxNode { + constructor(content) { + super(); + this.type = "Junk"; + this.annotations = []; + this.content = content; + } + + addAnnotation(annot) { + this.annotations.push(annot); + } +} + +class Span extends BaseNode { + constructor(start, end) { + super(); + this.type = "Span"; + this.start = start; + this.end = end; + } +} + +class Annotation extends SyntaxNode { + constructor(code, args = [], message) { + super(); + this.type = "Annotation"; + this.code = code; + this.args = args; + this.message = message; + } +} + +const ast = ({ + Resource: Resource, + Entry: Entry, + Message: Message, + Term: Term, + VariantList: VariantList, + Pattern: Pattern, + PatternElement: PatternElement, + TextElement: TextElement, + Placeable: Placeable, + Expression: Expression, + StringLiteral: StringLiteral, + NumberLiteral: NumberLiteral, + MessageReference: MessageReference, + TermReference: TermReference, + VariableReference: VariableReference, + FunctionReference: FunctionReference, + SelectExpression: SelectExpression, + AttributeExpression: AttributeExpression, + VariantExpression: VariantExpression, + CallExpression: CallExpression, + Attribute: Attribute, + Variant: Variant, + NamedArgument: NamedArgument, + Identifier: Identifier, + BaseComment: BaseComment, + Comment: Comment, + GroupComment: GroupComment, + ResourceComment: ResourceComment, + Junk: Junk, + Span: Span, + Annotation: Annotation +}); + +class ParseError extends Error { + constructor(code, ...args) { + super(); + this.code = code; + this.args = args; + this.message = getErrorMessage(code, args); + } +} + +/* eslint-disable complexity */ +function getErrorMessage(code, args) { + switch (code) { + case "E0001": + return "Generic error"; + case "E0002": + return "Expected an entry start"; + case "E0003": { + const [token] = args; + return `Expected token: "${token}"`; + } + case "E0004": { + const [range] = args; + return `Expected a character from range: "${range}"`; + } + case "E0005": { + const [id] = args; + return `Expected message "${id}" to have a value or attributes`; + } + case "E0006": { + const [id] = args; + return `Expected term "-${id}" to have a value`; + } + case "E0007": + return "Keyword cannot end with a whitespace"; + case "E0008": + return "The callee has to be an upper-case identifier or a term"; + case "E0009": + return "The key has to be a simple identifier"; + case "E0010": + return "Expected one of the variants to be marked as default (*)"; + case "E0011": + return 'Expected at least one variant after "->"'; + case "E0012": + return "Expected value"; + case "E0013": + return "Expected variant key"; + case "E0014": + return "Expected literal"; + case "E0015": + return "Only one variant can be marked as default (*)"; + case "E0016": + return "Message references cannot be used as selectors"; + case "E0017": + return "Terms cannot be used as selectors"; + case "E0018": + return "Attributes of messages cannot be used as selectors"; + case "E0019": + return "Attributes of terms cannot be used as placeables"; + case "E0020": + return "Unterminated string expression"; + case "E0021": + return "Positional arguments must not follow named arguments"; + case "E0022": + return "Named arguments must be unique"; + case "E0024": + return "Cannot access variants of a message."; + case "E0025": { + const [char] = args; + return `Unknown escape sequence: \\${char}.`; + } + case "E0026": { + const [sequence] = args; + return `Invalid Unicode escape sequence: ${sequence}.`; + } + case "E0027": + return "Unbalanced closing brace in TextElement."; + case "E0028": + return "Expected an inline expression"; + default: + return code; + } +} + +function includes(arr, elem) { + return arr.indexOf(elem) > -1; +} + +/* eslint no-magic-numbers: "off" */ + +class ParserStream { + constructor(string) { + this.string = string; + this.index = 0; + this.peekOffset = 0; + } + + charAt(offset) { + // When the cursor is at CRLF, return LF but don't move the cursor. + // The cursor still points to the EOL position, which in this case is the + // beginning of the compound CRLF sequence. This ensures slices of + // [inclusive, exclusive) continue to work properly. + if (this.string[offset] === "\r" + && this.string[offset + 1] === "\n") { + return "\n"; + } + + return this.string[offset]; + } + + get currentChar() { + return this.charAt(this.index); + } + + get currentPeek() { + return this.charAt(this.index + this.peekOffset); + } + + next() { + this.peekOffset = 0; + // Skip over the CRLF as if it was a single character. + if (this.string[this.index] === "\r" + && this.string[this.index + 1] === "\n") { + this.index++; + } + this.index++; + return this.string[this.index]; + } + + peek() { + // Skip over the CRLF as if it was a single character. + if (this.string[this.index + this.peekOffset] === "\r" + && this.string[this.index + this.peekOffset + 1] === "\n") { + this.peekOffset++; + } + this.peekOffset++; + return this.string[this.index + this.peekOffset]; + } + + resetPeek(offset = 0) { + this.peekOffset = offset; + } + + skipToPeek() { + this.index += this.peekOffset; + this.peekOffset = 0; + } +} + +const EOL = "\n"; +const EOF = undefined; +const SPECIAL_LINE_START_CHARS = ["}", ".", "[", "*"]; + +class FluentParserStream extends ParserStream { + peekBlankInline() { + const start = this.index + this.peekOffset; + while (this.currentPeek === " ") { + this.peek(); + } + return this.string.slice(start, this.index + this.peekOffset); + } + + skipBlankInline() { + const blank = this.peekBlankInline(); + this.skipToPeek(); + return blank; + } + + peekBlankBlock() { + let blank = ""; + while (true) { + const lineStart = this.peekOffset; + this.peekBlankInline(); + if (this.currentPeek === EOL) { + blank += EOL; + this.peek(); + continue; + } + if (this.currentPeek === EOF) { + // Treat the blank line at EOF as a blank block. + return blank; + } + // Any other char; reset to column 1 on this line. + this.resetPeek(lineStart); + return blank; + } + } + + skipBlankBlock() { + const blank = this.peekBlankBlock(); + this.skipToPeek(); + return blank; + } + + peekBlank() { + while (this.currentPeek === " " || this.currentPeek === EOL) { + this.peek(); + } + } + + skipBlank() { + this.peekBlank(); + this.skipToPeek(); + } + + expectChar(ch) { + if (this.currentChar === ch) { + this.next(); + return true; + } + + throw new ParseError("E0003", ch); + } + + expectLineEnd() { + if (this.currentChar === EOF) { + // EOF is a valid line end in Fluent. + return true; + } + + if (this.currentChar === EOL) { + this.next(); + return true; + } + + // Unicode Character 'SYMBOL FOR NEWLINE' (U+2424) + throw new ParseError("E0003", "\u2424"); + } + + takeChar(f) { + const ch = this.currentChar; + if (ch === EOF) { + return EOF; + } + if (f(ch)) { + this.next(); + return ch; + } + return null; + } + + isCharIdStart(ch) { + if (ch === EOF) { + return false; + } + + const cc = ch.charCodeAt(0); + return (cc >= 97 && cc <= 122) || // a-z + (cc >= 65 && cc <= 90); // A-Z + } + + isIdentifierStart() { + return this.isCharIdStart(this.currentPeek); + } + + isNumberStart() { + const ch = this.currentChar === "-" + ? this.peek() + : this.currentChar; + + if (ch === EOF) { + this.resetPeek(); + return false; + } + + const cc = ch.charCodeAt(0); + const isDigit = cc >= 48 && cc <= 57; // 0-9 + this.resetPeek(); + return isDigit; + } + + isCharPatternContinuation(ch) { + if (ch === EOF) { + return false; + } + + return !includes(SPECIAL_LINE_START_CHARS, ch); + } + + isValueStart() { + // Inline Patterns may start with any char. + const ch = this.currentPeek; + return ch !== EOL && ch !== EOF; + } + + isValueContinuation() { + const column1 = this.peekOffset; + this.peekBlankInline(); + + if (this.currentPeek === "{") { + this.resetPeek(column1); + return true; + } + + if (this.peekOffset - column1 === 0) { + return false; + } + + if (this.isCharPatternContinuation(this.currentPeek)) { + this.resetPeek(column1); + return true; + } + + return false; + } + + // -1 - any + // 0 - comment + // 1 - group comment + // 2 - resource comment + isNextLineComment(level = -1) { + if (this.currentChar !== EOL) { + return false; + } + + let i = 0; + + while (i <= level || (level === -1 && i < 3)) { + if (this.peek() !== "#") { + if (i <= level && level !== -1) { + this.resetPeek(); + return false; + } + break; + } + i++; + } + + // The first char after #, ## or ###. + const ch = this.peek(); + if (ch === " " || ch === EOL) { + this.resetPeek(); + return true; + } + + this.resetPeek(); + return false; + } + + isVariantStart() { + const currentPeekOffset = this.peekOffset; + if (this.currentPeek === "*") { + this.peek(); + } + if (this.currentPeek === "[") { + this.resetPeek(currentPeekOffset); + return true; + } + this.resetPeek(currentPeekOffset); + return false; + } + + isAttributeStart() { + return this.currentPeek === "."; + } + + skipToNextEntryStart(junkStart) { + let lastNewline = this.string.lastIndexOf(EOL, this.index); + if (junkStart < lastNewline) { + // Last seen newline is _after_ the junk start. It's safe to rewind + // without the risk of resuming at the same broken entry. + this.index = lastNewline; + } + while (this.currentChar) { + // We're only interested in beginnings of line. + if (this.currentChar !== EOL) { + this.next(); + continue; + } + + // Break if the first char in this line looks like an entry start. + const first = this.next(); + if (this.isCharIdStart(first) || first === "-" || first === "#") { + break; + } + } + } + + takeIDStart() { + if (this.isCharIdStart(this.currentChar)) { + const ret = this.currentChar; + this.next(); + return ret; + } + + throw new ParseError("E0004", "a-zA-Z"); + } + + takeIDChar() { + const closure = ch => { + const cc = ch.charCodeAt(0); + return ((cc >= 97 && cc <= 122) || // a-z + (cc >= 65 && cc <= 90) || // A-Z + (cc >= 48 && cc <= 57) || // 0-9 + cc === 95 || cc === 45); // _- + }; + + return this.takeChar(closure); + } + + takeDigit() { + const closure = ch => { + const cc = ch.charCodeAt(0); + return (cc >= 48 && cc <= 57); // 0-9 + }; + + return this.takeChar(closure); + } + + takeHexDigit() { + const closure = ch => { + const cc = ch.charCodeAt(0); + return (cc >= 48 && cc <= 57) // 0-9 + || (cc >= 65 && cc <= 70) // A-F + || (cc >= 97 && cc <= 102); // a-f + }; + + return this.takeChar(closure); + } +} + +/* eslint no-magic-numbers: [0] */ + + +const trailingWSRe = /[ \t\n\r]+$/; + + +function withSpan(fn) { + return function(ps, ...args) { + if (!this.withSpans) { + return fn.call(this, ps, ...args); + } + + const start = ps.index; + const node = fn.call(this, ps, ...args); + + // Don't re-add the span if the node already has it. This may happen when + // one decorated function calls another decorated function. + if (node.span) { + return node; + } + + const end = ps.index; + node.addSpan(start, end); + return node; + }; +} + + +class FluentParser { + constructor({ + withSpans = true, + } = {}) { + this.withSpans = withSpans; + + // Poor man's decorators. + const methodNames = [ + "getComment", "getMessage", "getTerm", "getAttribute", "getIdentifier", + "getVariant", "getNumber", "getPattern", "getVariantList", + "getTextElement", "getPlaceable", "getExpression", + "getInlineExpression", "getCallArgument", "getString", + "getSimpleExpression", "getLiteral", + ]; + for (const name of methodNames) { + this[name] = withSpan(this[name]); + } + } + + parse(source) { + const ps = new FluentParserStream(source); + ps.skipBlankBlock(); + + const entries = []; + let lastComment = null; + + while (ps.currentChar) { + const entry = this.getEntryOrJunk(ps); + const blankLines = ps.skipBlankBlock(); + + // Regular Comments require special logic. Comments may be attached to + // Messages or Terms if they are followed immediately by them. However + // they should parse as standalone when they're followed by Junk. + // Consequently, we only attach Comments once we know that the Message + // or the Term parsed successfully. + if (entry.type === "Comment" + && blankLines.length === 0 + && ps.currentChar) { + // Stash the comment and decide what to do with it in the next pass. + lastComment = entry; + continue; + } + + if (lastComment) { + if (entry.type === "Message" || entry.type === "Term") { + entry.comment = lastComment; + if (this.withSpans) { + entry.span.start = entry.comment.span.start; + } + } else { + entries.push(lastComment); + } + // In either case, the stashed comment has been dealt with; clear it. + lastComment = null; + } + + // No special logic for other types of entries. + entries.push(entry); + } + + const res = new Resource(entries); + + if (this.withSpans) { + res.addSpan(0, ps.index); + } + + return res; + } + + /* + * Parse the first Message or Term in `source`. + * + * Skip all encountered comments and start parsing at the first Message or + * Term start. Return Junk if the parsing is not successful. + * + * Preceding comments are ignored unless they contain syntax errors + * themselves, in which case Junk for the invalid comment is returned. + */ + parseEntry(source) { + const ps = new FluentParserStream(source); + ps.skipBlankBlock(); + + while (ps.currentChar === "#") { + const skipped = this.getEntryOrJunk(ps); + if (skipped.type === "Junk") { + // Don't skip Junk comments. + return skipped; + } + ps.skipBlankBlock(); + } + + return this.getEntryOrJunk(ps); + } + + getEntryOrJunk(ps) { + const entryStartPos = ps.index; + + try { + const entry = this.getEntry(ps); + ps.expectLineEnd(); + return entry; + } catch (err) { + if (!(err instanceof ParseError)) { + throw err; + } + + let errorIndex = ps.index; + ps.skipToNextEntryStart(entryStartPos); + const nextEntryStart = ps.index; + if (nextEntryStart < errorIndex) { + // The position of the error must be inside of the Junk's span. + errorIndex = nextEntryStart; + } + + // Create a Junk instance + const slice = ps.string.substring(entryStartPos, nextEntryStart); + const junk = new Junk(slice); + if (this.withSpans) { + junk.addSpan(entryStartPos, nextEntryStart); + } + const annot = new Annotation(err.code, err.args, err.message); + annot.addSpan(errorIndex, errorIndex); + junk.addAnnotation(annot); + return junk; + } + } + + getEntry(ps) { + if (ps.currentChar === "#") { + return this.getComment(ps); + } + + if (ps.currentChar === "-") { + return this.getTerm(ps); + } + + if (ps.isIdentifierStart()) { + return this.getMessage(ps); + } + + throw new ParseError("E0002"); + } + + getComment(ps) { + // 0 - comment + // 1 - group comment + // 2 - resource comment + let level = -1; + let content = ""; + + while (true) { + let i = -1; + while (ps.currentChar === "#" && (i < (level === -1 ? 2 : level))) { + ps.next(); + i++; + } + + if (level === -1) { + level = i; + } + + if (ps.currentChar !== EOL) { + ps.expectChar(" "); + let ch; + while ((ch = ps.takeChar(x => x !== EOL))) { + content += ch; + } + } + + if (ps.isNextLineComment(level)) { + content += ps.currentChar; + ps.next(); + } else { + break; + } + } + + let Comment$$1; + switch (level) { + case 0: + Comment$$1 = Comment; + break; + case 1: + Comment$$1 = GroupComment; + break; + case 2: + Comment$$1 = ResourceComment; + break; + } + return new Comment$$1(content); + } + + getMessage(ps) { + const id = this.getIdentifier(ps); + + ps.skipBlankInline(); + ps.expectChar("="); + + const value = this.maybeGetPattern(ps); + const attrs = this.getAttributes(ps); + + if (value === null && attrs.length === 0) { + throw new ParseError("E0005", id.name); + } + + return new Message(id, value, attrs); + } + + getTerm(ps) { + ps.expectChar("-"); + const id = this.getIdentifier(ps); + + ps.skipBlankInline(); + ps.expectChar("="); + + // Syntax 0.8 compat: VariantLists are supported but deprecated. They can + // only be found as values of Terms. Nested VariantLists are not allowed. + const value = this.maybeGetVariantList(ps) || this.maybeGetPattern(ps); + if (value === null) { + throw new ParseError("E0006", id.name); + } + + const attrs = this.getAttributes(ps); + return new Term(id, value, attrs); + } + + getAttribute(ps) { + ps.expectChar("."); + + const key = this.getIdentifier(ps); + + ps.skipBlankInline(); + ps.expectChar("="); + + const value = this.maybeGetPattern(ps); + if (value === null) { + throw new ParseError("E0012"); + } + + return new Attribute(key, value); + } + + getAttributes(ps) { + const attrs = []; + ps.peekBlank(); + while (ps.isAttributeStart()) { + ps.skipToPeek(); + const attr = this.getAttribute(ps); + attrs.push(attr); + ps.peekBlank(); + } + return attrs; + } + + getIdentifier(ps) { + let name = ps.takeIDStart(); + + let ch; + while ((ch = ps.takeIDChar())) { + name += ch; + } + + return new Identifier(name); + } + + getVariantKey(ps) { + const ch = ps.currentChar; + + if (ch === EOF) { + throw new ParseError("E0013"); + } + + const cc = ch.charCodeAt(0); + + if ((cc >= 48 && cc <= 57) || cc === 45) { // 0-9, - + return this.getNumber(ps); + } + + return this.getIdentifier(ps); + } + + getVariant(ps, {hasDefault}) { + let defaultIndex = false; + + if (ps.currentChar === "*") { + if (hasDefault) { + throw new ParseError("E0015"); + } + ps.next(); + defaultIndex = true; + } + + ps.expectChar("["); + + ps.skipBlank(); + + const key = this.getVariantKey(ps); + + ps.skipBlank(); + ps.expectChar("]"); + + const value = this.maybeGetPattern(ps); + if (value === null) { + throw new ParseError("E0012"); + } + + return new Variant(key, value, defaultIndex); + } + + getVariants(ps) { + const variants = []; + let hasDefault = false; + + ps.skipBlank(); + while (ps.isVariantStart()) { + const variant = this.getVariant(ps, {hasDefault}); + + if (variant.default) { + hasDefault = true; + } + + variants.push(variant); + ps.expectLineEnd(); + ps.skipBlank(); + } + + if (variants.length === 0) { + throw new ParseError("E0011"); + } + + if (!hasDefault) { + throw new ParseError("E0010"); + } + + return variants; + } + + getDigits(ps) { + let num = ""; + + let ch; + while ((ch = ps.takeDigit())) { + num += ch; + } + + if (num.length === 0) { + throw new ParseError("E0004", "0-9"); + } + + return num; + } + + getNumber(ps) { + let num = ""; + + if (ps.currentChar === "-") { + num += "-"; + ps.next(); + } + + num = `${num}${this.getDigits(ps)}`; + + if (ps.currentChar === ".") { + num += "."; + ps.next(); + num = `${num}${this.getDigits(ps)}`; + } + + return new NumberLiteral(num); + } + + // maybeGetPattern distinguishes between patterns which start on the same line + // as the identifier (a.k.a. inline signleline patterns and inline multiline + // patterns) and patterns which start on a new line (a.k.a. block multiline + // patterns). The distinction is important for the dedentation logic: the + // indent of the first line of a block pattern must be taken into account when + // calculating the maximum common indent. + maybeGetPattern(ps) { + ps.peekBlankInline(); + if (ps.isValueStart()) { + ps.skipToPeek(); + return this.getPattern(ps, {isBlock: false}); + } + + ps.peekBlankBlock(); + if (ps.isValueContinuation()) { + ps.skipToPeek(); + return this.getPattern(ps, {isBlock: true}); + } + + return null; + } + + // Deprecated in Syntax 0.8. VariantLists are only allowed as values of Terms. + // Values of Messages, Attributes and Variants must be Patterns. This method + // is only used in getTerm. + maybeGetVariantList(ps) { + ps.peekBlank(); + if (ps.currentPeek === "{") { + const start = ps.peekOffset; + ps.peek(); + ps.peekBlankInline(); + if (ps.currentPeek === EOL) { + ps.peekBlank(); + if (ps.isVariantStart()) { + ps.resetPeek(start); + ps.skipToPeek(); + return this.getVariantList(ps); + } + } + } + + ps.resetPeek(); + return null; + } + + getVariantList(ps) { + ps.expectChar("{"); + var variants = this.getVariants(ps); + ps.expectChar("}"); + return new VariantList(variants); + } + + getPattern(ps, {isBlock}) { + const elements = []; + if (isBlock) { + // A block pattern is a pattern which starts on a new line. Store and + // measure the indent of this first line for the dedentation logic. + const blankStart = ps.index; + const firstIndent = ps.skipBlankInline(); + elements.push(this.getIndent(ps, firstIndent, blankStart)); + var commonIndentLength = firstIndent.length; + } else { + var commonIndentLength = Infinity; + } + + let ch; + elements: while ((ch = ps.currentChar)) { + switch (ch) { + case EOL: { + const blankStart = ps.index; + const blankLines = ps.peekBlankBlock(); + if (ps.isValueContinuation()) { + ps.skipToPeek(); + const indent = ps.skipBlankInline(); + commonIndentLength = Math.min(commonIndentLength, indent.length); + elements.push(this.getIndent(ps, blankLines + indent, blankStart)); + continue elements; + } + + // The end condition for getPattern's while loop is a newline + // which is not followed by a valid pattern continuation. + ps.resetPeek(); + break elements; + } + case "{": + elements.push(this.getPlaceable(ps)); + continue elements; + case "}": + throw new ParseError("E0027"); + default: + const element = this.getTextElement(ps); + elements.push(element); + } + } + + const dedented = this.dedent(elements, commonIndentLength); + return new Pattern(dedented); + } + + // Create a token representing an indent. It's not part of the AST and it will + // be trimmed and merged into adjacent TextElements, or turned into a new + // TextElement, if it's surrounded by two Placeables. + getIndent(ps, value, start) { + return { + type: "Indent", + span: {start, end: ps.index}, + value, + }; + } + + // Dedent a list of elements by removing the maximum common indent from the + // beginning of text lines. The common indent is calculated in getPattern. + dedent(elements, commonIndent) { + const trimmed = []; + + for (let element of elements) { + if (element.type === "Placeable") { + trimmed.push(element); + continue; + } + + if (element.type === "Indent") { + // Strip common indent. + element.value = element.value.slice( + 0, element.value.length - commonIndent); + if (element.value.length === 0) { + continue; + } + } + + let prev = trimmed[trimmed.length - 1]; + if (prev && prev.type === "TextElement") { + // Join adjacent TextElements by replacing them with their sum. + const sum = new TextElement(prev.value + element.value); + if (this.withSpans) { + sum.addSpan(prev.span.start, element.span.end); + } + trimmed[trimmed.length - 1] = sum; + continue; + } + + if (element.type === "Indent") { + // If the indent hasn't been merged into a preceding TextElement, + // convert it into a new TextElement. + const textElement = new TextElement(element.value); + if (this.withSpans) { + textElement.addSpan(element.span.start, element.span.end); + } + element = textElement; + } + + trimmed.push(element); + } + + // Trim trailing whitespace from the Pattern. + const lastElement = trimmed[trimmed.length - 1]; + if (lastElement.type === "TextElement") { + lastElement.value = lastElement.value.replace(trailingWSRe, ""); + if (lastElement.value.length === 0) { + trimmed.pop(); + } + } + + return trimmed; + } + + getTextElement(ps) { + let buffer = ""; + + let ch; + while ((ch = ps.currentChar)) { + if (ch === "{" || ch === "}") { + return new TextElement(buffer); + } + + if (ch === EOL) { + return new TextElement(buffer); + } + + buffer += ch; + ps.next(); + } + + return new TextElement(buffer); + } + + getEscapeSequence(ps) { + const next = ps.currentChar; + + switch (next) { + case "\\": + case "\"": + ps.next(); + return [`\\${next}`, next]; + case "u": + return this.getUnicodeEscapeSequence(ps, next, 4); + case "U": + return this.getUnicodeEscapeSequence(ps, next, 6); + default: + throw new ParseError("E0025", next); + } + } + + getUnicodeEscapeSequence(ps, u, digits) { + ps.expectChar(u); + + let sequence = ""; + for (let i = 0; i < digits; i++) { + const ch = ps.takeHexDigit(); + + if (!ch) { + throw new ParseError( + "E0026", `\\${u}${sequence}${ps.currentChar}`); + } + + sequence += ch; + } + + const codepoint = parseInt(sequence, 16); + const unescaped = codepoint <= 0xD7FF || 0xE000 <= codepoint + // It's a Unicode scalar value. + ? String.fromCodePoint(codepoint) + // Escape sequences reresenting surrogate code points are well-formed + // but invalid in Fluent. Replace them with U+FFFD REPLACEMENT + // CHARACTER. + : "�"; + return [`\\${u}${sequence}`, unescaped]; + } + + getPlaceable(ps) { + ps.expectChar("{"); + ps.skipBlank(); + const expression = this.getExpression(ps); + ps.expectChar("}"); + return new Placeable(expression); + } + + getExpression(ps) { + const selector = this.getInlineExpression(ps); + ps.skipBlank(); + + if (ps.currentChar === "-") { + if (ps.peek() !== ">") { + ps.resetPeek(); + return selector; + } + + if (selector.type === "MessageReference") { + throw new ParseError("E0016"); + } + + if (selector.type === "AttributeExpression" + && selector.ref.type === "MessageReference") { + throw new ParseError("E0018"); + } + + if (selector.type === "TermReference" + || selector.type === "VariantExpression") { + throw new ParseError("E0017"); + } + + if (selector.type === "CallExpression" + && selector.callee.type === "TermReference") { + throw new ParseError("E0017"); + } + + ps.next(); + ps.next(); + + ps.skipBlankInline(); + ps.expectLineEnd(); + + const variants = this.getVariants(ps); + return new SelectExpression(selector, variants); + } + + if (selector.type === "AttributeExpression" + && selector.ref.type === "TermReference") { + throw new ParseError("E0019"); + } + + if (selector.type === "CallExpression" + && selector.callee.type === "AttributeExpression") { + throw new ParseError("E0019"); + } + + return selector; + } + + getInlineExpression(ps) { + if (ps.currentChar === "{") { + return this.getPlaceable(ps); + } + + let expr = this.getSimpleExpression(ps); + switch (expr.type) { + case "NumberLiteral": + case "StringLiteral": + case "VariableReference": + return expr; + case "MessageReference": { + if (ps.currentChar === ".") { + ps.next(); + const attr = this.getIdentifier(ps); + return new AttributeExpression(expr, attr); + } + + if (ps.currentChar === "(") { + // It's a Function. Ensure it's all upper-case. + if (!/^[A-Z][A-Z_?-]*$/.test(expr.id.name)) { + throw new ParseError("E0008"); + } + + const func = new FunctionReference(expr.id); + if (this.withSpans) { + func.addSpan(expr.span.start, expr.span.end); + } + return new CallExpression(func, ...this.getCallArguments(ps)); + } + + return expr; + } + case "TermReference": { + if (ps.currentChar === "[") { + ps.next(); + const key = this.getVariantKey(ps); + ps.expectChar("]"); + return new VariantExpression(expr, key); + } + + if (ps.currentChar === ".") { + ps.next(); + const attr = this.getIdentifier(ps); + expr = new AttributeExpression(expr, attr); + } + + if (ps.currentChar === "(") { + return new CallExpression(expr, ...this.getCallArguments(ps)); + } + + return expr; + } + default: + throw new ParseError("E0028"); + } + } + + getSimpleExpression(ps) { + if (ps.isNumberStart()) { + return this.getNumber(ps); + } + + if (ps.currentChar === '"') { + return this.getString(ps); + } + + if (ps.currentChar === "$") { + ps.next(); + const id = this.getIdentifier(ps); + return new VariableReference(id); + } + + if (ps.currentChar === "-") { + ps.next(); + const id = this.getIdentifier(ps); + return new TermReference(id); + } + + if (ps.isIdentifierStart()) { + const id = this.getIdentifier(ps); + return new MessageReference(id); + } + + throw new ParseError("E0028"); + } + + getCallArgument(ps) { + const exp = this.getInlineExpression(ps); + + ps.skipBlank(); + + if (ps.currentChar !== ":") { + return exp; + } + + if (exp.type !== "MessageReference") { + throw new ParseError("E0009"); + } + + ps.next(); + ps.skipBlank(); + + const value = this.getLiteral(ps); + return new NamedArgument(exp.id, value); + } + + getCallArguments(ps) { + const positional = []; + const named = []; + const argumentNames = new Set(); + + ps.expectChar("("); + ps.skipBlank(); + + while (true) { + if (ps.currentChar === ")") { + break; + } + + const arg = this.getCallArgument(ps); + if (arg.type === "NamedArgument") { + if (argumentNames.has(arg.name.name)) { + throw new ParseError("E0022"); + } + named.push(arg); + argumentNames.add(arg.name.name); + } else if (argumentNames.size > 0) { + throw new ParseError("E0021"); + } else { + positional.push(arg); + } + + ps.skipBlank(); + + if (ps.currentChar === ",") { + ps.next(); + ps.skipBlank(); + continue; + } + + break; + } + + ps.expectChar(")"); + return [positional, named]; + } + + getString(ps) { + let raw = ""; + let value = ""; + + ps.expectChar("\""); + + let ch; + while ((ch = ps.takeChar(x => x !== '"' && x !== EOL))) { + if (ch === "\\") { + const [sequence, unescaped] = this.getEscapeSequence(ps); + raw += sequence; + value += unescaped; + } else { + raw += ch; + value += ch; + } + } + + if (ps.currentChar === EOL) { + throw new ParseError("E0020"); + } + + ps.expectChar("\""); + + return new StringLiteral(raw, value); + } + + getLiteral(ps) { + if (ps.isNumberStart()) { + return this.getNumber(ps); + } + + if (ps.currentChar === '"') { + return this.getString(ps); + } + + throw new ParseError("E0014"); + } +} + +function indent(content) { + return content.split("\n").join("\n "); +} + +function includesNewLine(elem) { + return elem.type === "TextElement" && includes(elem.value, "\n"); +} + +function isSelectExpr(elem) { + return elem.type === "Placeable" + && elem.expression.type === "SelectExpression"; +} + +// Bit masks representing the state of the serializer. +const HAS_ENTRIES = 1; + +class FluentSerializer { + constructor({ withJunk = false } = {}) { + this.withJunk = withJunk; + } + + serialize(resource) { + if (resource.type !== "Resource") { + throw new Error(`Unknown resource type: ${resource.type}`); + } + + let state = 0; + const parts = []; + + for (const entry of resource.body) { + if (entry.type !== "Junk" || this.withJunk) { + parts.push(this.serializeEntry(entry, state)); + if (!(state & HAS_ENTRIES)) { + state |= HAS_ENTRIES; + } + } + } + + return parts.join(""); + } + + serializeEntry(entry, state = 0) { + switch (entry.type) { + case "Message": + return serializeMessage(entry); + case "Term": + return serializeTerm(entry); + case "Comment": + if (state & HAS_ENTRIES) { + return `\n${serializeComment(entry, "#")}\n`; + } + return `${serializeComment(entry, "#")}\n`; + case "GroupComment": + if (state & HAS_ENTRIES) { + return `\n${serializeComment(entry, "##")}\n`; + } + return `${serializeComment(entry, "##")}\n`; + case "ResourceComment": + if (state & HAS_ENTRIES) { + return `\n${serializeComment(entry, "###")}\n`; + } + return `${serializeComment(entry, "###")}\n`; + case "Junk": + return serializeJunk(entry); + default : + throw new Error(`Unknown entry type: ${entry.type}`); + } + } + + serializeExpression(expr) { + return serializeExpression(expr); + } +} + + +function serializeComment(comment, prefix = "#") { + const prefixed = comment.content.split("\n").map( + line => line.length ? `${prefix} ${line}` : prefix + ).join("\n"); + // Add the trailing newline. + return `${prefixed}\n`; +} + + +function serializeJunk(junk) { + return junk.content; +} + + +function serializeMessage(message) { + const parts = []; + + if (message.comment) { + parts.push(serializeComment(message.comment)); + } + + parts.push(`${message.id.name} =`); + + if (message.value) { + parts.push(serializeValue(message.value)); + } + + for (const attribute of message.attributes) { + parts.push(serializeAttribute(attribute)); + } + + parts.push("\n"); + return parts.join(""); +} + + +function serializeTerm(term) { + const parts = []; + + if (term.comment) { + parts.push(serializeComment(term.comment)); + } + + parts.push(`-${term.id.name} =`); + parts.push(serializeValue(term.value)); + + for (const attribute of term.attributes) { + parts.push(serializeAttribute(attribute)); + } + + parts.push("\n"); + return parts.join(""); +} + + +function serializeAttribute(attribute) { + const value = indent(serializeValue(attribute.value)); + return `\n .${attribute.id.name} =${value}`; +} + + +function serializeValue(value) { + switch (value.type) { + case "Pattern": + return serializePattern(value); + case "VariantList": + return serializeVariantList(value); + default: + throw new Error(`Unknown value type: ${value.type}`); + } +} + + +function serializePattern(pattern) { + const content = pattern.elements.map(serializeElement).join(""); + const startOnNewLine = + pattern.elements.some(isSelectExpr) || + pattern.elements.some(includesNewLine); + + if (startOnNewLine) { + return `\n ${indent(content)}`; + } + + return ` ${content}`; +} + + +function serializeVariantList(varlist) { + const content = varlist.variants.map(serializeVariant).join(""); + return `\n {${indent(content)}\n }`; +} + + +function serializeVariant(variant) { + const key = serializeVariantKey(variant.key); + const value = indent(serializeValue(variant.value)); + + if (variant.default) { + return `\n *[${key}]${value}`; + } + + return `\n [${key}]${value}`; +} + + +function serializeElement(element) { + switch (element.type) { + case "TextElement": + return element.value; + case "Placeable": + return serializePlaceable(element); + default: + throw new Error(`Unknown element type: ${element.type}`); + } +} + + +function serializePlaceable(placeable) { + const expr = placeable.expression; + + switch (expr.type) { + case "Placeable": + return `{${serializePlaceable(expr)}}`; + case "SelectExpression": + // Special-case select expression to control the whitespace around the + // opening and the closing brace. + return `{ ${serializeSelectExpression(expr)}}`; + default: + return `{ ${serializeExpression(expr)} }`; + } +} + + +function serializeExpression(expr) { + switch (expr.type) { + case "StringLiteral": + return `"${expr.raw}"`; + case "NumberLiteral": + return expr.value; + case "MessageReference": + case "FunctionReference": + return expr.id.name; + case "TermReference": + return `-${expr.id.name}`; + case "VariableReference": + return `$${expr.id.name}`; + case "AttributeExpression": + return serializeAttributeExpression(expr); + case "VariantExpression": + return serializeVariantExpression(expr); + case "CallExpression": + return serializeCallExpression(expr); + case "SelectExpression": + return serializeSelectExpression(expr); + case "Placeable": + return serializePlaceable(expr); + default: + throw new Error(`Unknown expression type: ${expr.type}`); + } +} + + +function serializeSelectExpression(expr) { + const parts = []; + const selector = `${serializeExpression(expr.selector)} ->`; + parts.push(selector); + + for (const variant of expr.variants) { + parts.push(serializeVariant(variant)); + } + + parts.push("\n"); + return parts.join(""); +} + + +function serializeAttributeExpression(expr) { + const ref = serializeExpression(expr.ref); + return `${ref}.${expr.name.name}`; +} + + +function serializeVariantExpression(expr) { + const ref = serializeExpression(expr.ref); + const key = serializeVariantKey(expr.key); + return `${ref}[${key}]`; +} + + +function serializeCallExpression(expr) { + const callee = serializeExpression(expr.callee); + const positional = expr.positional.map(serializeExpression).join(", "); + const named = expr.named.map(serializeNamedArgument).join(", "); + if (expr.positional.length > 0 && expr.named.length > 0) { + return `${callee}(${positional}, ${named})`; + } + return `${callee}(${positional || named})`; +} + + +function serializeNamedArgument(arg) { + const value = serializeExpression(arg.value); + return `${arg.name.name}: ${value}`; +} + + +function serializeVariantKey(key) { + switch (key.type) { + case "Identifier": + return key.name; + default: + return serializeExpression(key); + } +} + +/* eslint object-shorthand: "off", + no-unused-vars: "off", + no-redeclare: "off", + comma-dangle: "off", + no-labels: "off" */ + +this.EXPORTED_SYMBOLS = [ + "FluentParser", + "FluentSerializer", + ...Object.keys(ast), +]; diff --git a/intl/l10n/moz.build b/intl/l10n/moz.build index 85be6e0f9ce7..ad8b8a152aeb 100644 --- a/intl/l10n/moz.build +++ b/intl/l10n/moz.build @@ -11,6 +11,10 @@ EXTRA_JS_MODULES += [ 'Localization.jsm', ] +TESTING_JS_MODULES += [ + 'FluentSyntax.jsm', +] + XPIDL_SOURCES += [ 'mozIDOMLocalization.idl', ] diff --git a/ipc/ipdl/ipdl/cxx/cgen.py b/ipc/ipdl/ipdl/cxx/cgen.py index 3ecf20079bc7..ccab6f507412 100644 --- a/ipc/ipdl/ipdl/cxx/cgen.py +++ b/ipc/ipdl/ipdl/cxx/cgen.py @@ -256,8 +256,8 @@ class CxxCodeGen(CodePrinter, Visitor): self.write(' = 0') def visitMethodDefn(self, md): - if md.decl.methodspec == MethodSpec.PURE: - return + # Method specifiers are for decls, not defns. + assert md.decl.methodspec == MethodSpec.NONE self.printdent() md.decl.accept(self) diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 37b330cd1930..584297c093dd 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -4827,16 +4827,22 @@ methodDefns.""" for i, stmt in enumerate(cls.stmts): if isinstance(stmt, MethodDefn) and not stmt.decl.force_inline: - decl, defn = _splitMethodDefn(stmt, cls) + decl, defn = _splitMethodDeclDefn(stmt, cls) cls.stmts[i] = StmtDecl(decl) - defns.addstmts([defn, Whitespace.NL]) + if defn: + defns.addstmts([defn, Whitespace.NL]) return cls, defns -def _splitMethodDefn(md, cls): +def _splitMethodDeclDefn(md, cls): + # Pure methods have decls but no defns. + if md.decl.methodspec == MethodSpec.PURE: + return md.decl, None + saveddecl = deepcopy(md.decl) md.decl.cls = cls + # Don't emit method specifiers on method defns. md.decl.methodspec = MethodSpec.NONE md.decl.warn_unused = False md.decl.only_for_definition = True diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index 123ae527c4ac..f6a6afbc6d17 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -7443,10 +7443,10 @@ gcstats::ZoneGCStats GCRuntime::scanZonesBeforeGC() { zoneStats.compartmentCount += zone->compartments().length(); if (zone->canCollect()) { zoneStats.collectableZoneCount++; - } - if (zone->isGCScheduled()) { - zoneStats.collectedZoneCount++; - zoneStats.collectedCompartmentCount += zone->compartments().length(); + if (zone->isGCScheduled()) { + zoneStats.collectedZoneCount++; + zoneStats.collectedCompartmentCount += zone->compartments().length(); + } } } diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 9111bc8eaec6..9ea80b878295 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -318,7 +318,7 @@ fuzzy-if(Android,0-3,0-50) fuzzy-if(skiaContent,0-1,0-133) == 273681-1.html 2736 == 283686-2.html 283686-2-ref.html == 283686-3.html about:blank == 289384-1.xhtml 289384-ref.xhtml -random-if(d2d) fuzzy-if(Android,0-8,0-1439) fuzzy-if(webrender,0-6,0-1124) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures +random-if(d2d) fuzzy-if(Android,0-8,0-1439) fuzzy-if(webrender,0-6,0-1124) skip-if(webrender&>kWidget) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures == 290129-1.html 290129-1-ref.html == 291078-1.html 291078-1-ref.html == 291078-2.html 291078-2-ref.html diff --git a/media/webrtc/trunk/webrtc/voice_engine/channel.cc b/media/webrtc/trunk/webrtc/voice_engine/channel.cc index 99b27f399229..4b9919a14593 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/channel.cc +++ b/media/webrtc/trunk/webrtc/voice_engine/channel.cc @@ -1277,6 +1277,7 @@ void Channel::OnRtpPacket(const RtpPacketReceived& packet) { rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); if (header.payload_type_frequency >= 0) { bool in_order = IsPacketInOrder(header); + statistics_proxy_->OnSendCodecFrequencyChanged(header.payload_type_frequency); rtp_receive_statistics_->IncomingPacket( header, packet.size(), IsPacketRetransmitted(header, in_order)); rtp_payload_registry_->SetIncomingPayloadType(header); diff --git a/memory/replace/dmd/DMD.cpp b/memory/replace/dmd/DMD.cpp index e803f5c7332a..358218df5562 100644 --- a/memory/replace/dmd/DMD.cpp +++ b/memory/replace/dmd/DMD.cpp @@ -133,7 +133,7 @@ class InfallibleAllocPolicy { return p; } - static void* calloc_(size_t aSize) { + static void* calloc_(size_t aCount, size_t aSize) { void* p = gMallocTable.calloc(1, aSize); ExitOnFailure(p); return p; @@ -1127,9 +1127,12 @@ static void* replace_calloc(size_t aCount, size_t aSize) { Thread* t = Thread::Fetch(); if (t->InterceptsAreBlocked()) { - return InfallibleAllocPolicy::calloc_(aCount * aSize); + return InfallibleAllocPolicy::calloc_(aCount, aSize); } + // |aCount * aSize| could overflow, but if that happens then + // |gMallocTable.calloc()| will return nullptr and |AllocCallback()| will + // return immediately without using the overflowed value. void* ptr = gMallocTable.calloc(aCount, aSize); AllocCallback(ptr, aCount * aSize, t); return ptr; diff --git a/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java b/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java index c43cc2669b6a..b099b83ae874 100644 --- a/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java +++ b/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java @@ -195,7 +195,10 @@ public class LauncherActivity extends Activity { return; } final String deepLink = intent.getData().getHost(); - final String uid = intent.getData().getQueryParameter("uid").replaceAll("\\n", ""); + String uid = intent.getData().getQueryParameter("uid"); + if (uid != null) { + uid = uid.replaceAll("\\n", ""); + } final String localUid = MmaDelegate.getDeviceId(LauncherActivity.this); final boolean isMmaDeepLink = uid != null && localUid != null && uid.equals(localUid); diff --git a/modules/libjar/test/mochitest/test_bug1173171.html b/modules/libjar/test/mochitest/test_bug1173171.html index fdcc37f2d85d..4cd02654982b 100644 --- a/modules/libjar/test/mochitest/test_bug1173171.html +++ b/modules/libjar/test/mochitest/test_bug1173171.html @@ -21,18 +21,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1173171 // __xhr(method, url, responseType__. // A simple async XMLHttpRequest call. // Returns a promise with the response. -let xhr = function (method, url, responseType) { - return new Promise(function (resolve, reject) { - let xhr = new XMLHttpRequest(); - xhr.open(method, url, true); - xhr.onload = function () { - resolve(xhr.response); +let xhr = function(method, url, responseType) { + return new Promise(function(resolve, reject) { + let xhrInstance = new XMLHttpRequest(); + xhrInstance.open(method, url, true); + xhrInstance.onload = function() { + resolve(xhrInstance.response); }; - xhr.onerror = function() { + xhrInstance.onerror = function() { resolve(null); }; - xhr.responseType = responseType; - xhr.send(); + xhrInstance.responseType = responseType; + xhrInstance.send(); }); }; @@ -40,7 +40,6 @@ let jarURL = "jar:http://mochi.test:8888/tests/modules/libjar/test/mochitest/bug // Test behavior when blocking is deactivated and activated. add_task(async function() { - let shouldBlock = true; let response = await xhr("GET", jarURL, "document"); is(response, null, "Remote jars should be blocked."); }); diff --git a/modules/libjar/test/unit/test_bug1328865.js b/modules/libjar/test/unit/test_bug1328865.js index d464a70a1e83..ec3554c181ce 100644 --- a/modules/libjar/test/unit/test_bug1328865.js +++ b/modules/libjar/test/unit/test_bug1328865.js @@ -4,15 +4,14 @@ "use strict"; +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); // Check that reading non existant inner jars results in the right error add_task(async function() { var file = do_get_file("data/test_bug597702.zip"); - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var outerJarBase = "jar:" + ios.newFileURI(file).spec + "!/"; + var outerJarBase = "jar:" + Services.io.newFileURI(file).spec + "!/"; var goodSpec = "jar:" + outerJarBase + "inner.jar!/hello#!/ignore%20this%20part"; var goodChannel = NetUtil.newChannel({uri: goodSpec, loadUsingSystemPrincipal: true}); var instr = goodChannel.open(); @@ -22,9 +21,7 @@ add_task(async function() { add_task(async function() { var file = do_get_file("data/test_bug597702.zip"); - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var outerJarBase = "jar:" + ios.newFileURI(file).spec + "!/"; + var outerJarBase = "jar:" + Services.io.newFileURI(file).spec + "!/"; var goodSpec = "jar:" + outerJarBase + "inner.jar!/hello?ignore%20this%20part!/"; var goodChannel = NetUtil.newChannel({uri: goodSpec, loadUsingSystemPrincipal: true}); var instr = goodChannel.open(); @@ -34,9 +31,7 @@ add_task(async function() { add_task(async function() { var file = do_get_file("data/test_bug597702.zip"); - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var outerJarBase = "jar:" + ios.newFileURI(file).spec + "!/"; + var outerJarBase = "jar:" + Services.io.newFileURI(file).spec + "!/"; var goodSpec = "jar:" + outerJarBase + "inner.jar!/hello?ignore#this!/part"; var goodChannel = NetUtil.newChannel({uri: goodSpec, loadUsingSystemPrincipal: true}); var instr = goodChannel.open(); diff --git a/modules/libjar/test/unit/test_bug278262.js b/modules/libjar/test/unit/test_bug278262.js index c4cb0df64257..0d48b9763f40 100644 --- a/modules/libjar/test/unit/test_bug278262.js +++ b/modules/libjar/test/unit/test_bug278262.js @@ -1,11 +1,11 @@ // Regression test for bug 278262 - JAR URIs should resolve relative URIs in the base section. +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + const path = "data/test_bug333423.zip"; function test_relative_sub() { - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - + var ios = Services.io; var spec = "jar:" + ios.newFileURI(do_get_file(path)).spec + "!/"; var base = ios.newURI(spec); var uri = ios.newURI("../modules/libjar", null, base); @@ -13,14 +13,12 @@ function test_relative_sub() { // This is the URI we expect to see. var expected = "jar:" + ios.newFileURI(do_get_file(path)).spec + "!/modules/libjar"; - + Assert.equal(uri.spec, expected); } function test_relative_base() { - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - + var ios = Services.io; var base = ios.newFileURI(do_get_file("data/empty")); var uri = ios.newURI("jar:../" + path + "!/", null, base); diff --git a/modules/libjar/test/unit/test_bug333423.js b/modules/libjar/test/unit/test_bug333423.js index 08e8256f50fb..bf4ee2403f29 100644 --- a/modules/libjar/test/unit/test_bug333423.js +++ b/modules/libjar/test/unit/test_bug333423.js @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// Regression test for bug 333423 - crash enumerating entries of a +// Regression test for bug 333423 - crash enumerating entries of a // closed nsIZipReader function run_test() { // the build script have created the zip we can test on in the current dir. @@ -14,6 +14,6 @@ function run_test() { createInstance(Ci.nsIZipReader); zipreader.open(file); zipreader.close(); - var entries = zipreader.findEntries('*.*'); + var entries = zipreader.findEntries("*.*"); Assert.ok(!entries.hasMore()); // this shouldn't crash } diff --git a/modules/libjar/test/unit/test_bug370103.js b/modules/libjar/test/unit/test_bug370103.js index 3de7c6b10f12..7197c9320894 100644 --- a/modules/libjar/test/unit/test_bug370103.js +++ b/modules/libjar/test/unit/test_bug370103.js @@ -1,13 +1,12 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); // Regression test for bug 370103 - crash when passing a null listener to // nsIChannel.asyncOpen function run_test() { // Compose the jar: url - var ioService = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); var file = do_get_file("data/test_bug370103.jar"); - var url = ioService.newFileURI(file).spec; + var url = Services.io.newFileURI(file).spec; url = "jar:" + url + "!/test_bug370103"; // Try opening channel with null listener @@ -16,8 +15,7 @@ function run_test() { var exception = false; try { channel.asyncOpen(null); - } - catch(e) { + } catch (e) { exception = true; } diff --git a/modules/libjar/test/unit/test_bug379841.js b/modules/libjar/test/unit/test_bug379841.js index d902bfdaed1e..4ef3f275e369 100644 --- a/modules/libjar/test/unit/test_bug379841.js +++ b/modules/libjar/test/unit/test_bug379841.js @@ -14,7 +14,7 @@ function run_test() { createInstance(Ci.nsIZipReader); zipReader.open(file); var entry = zipReader.getEntry(ENTRY_NAME); - var diff = Math.abs(entry.lastModifiedTime - ENTRY_TIME.getTime()*1000); + var diff = Math.abs(entry.lastModifiedTime - ENTRY_TIME.getTime() * 1000); zipReader.close(); if (diff >= MAX_TIME_DIFF) do_throw(diff); diff --git a/modules/libjar/test/unit/test_bug589292.js b/modules/libjar/test/unit/test_bug589292.js index 273406d76074..862aed236e73 100644 --- a/modules/libjar/test/unit/test_bug589292.js +++ b/modules/libjar/test/unit/test_bug589292.js @@ -1,18 +1,16 @@ // Make sure we behave appropriately when asking for content-disposition +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); const path = "data/test_bug589292.zip"; function run_test() { - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var spec = "jar:" + ios.newFileURI(do_get_file(path)).spec + "!/foo.txt"; + var spec = "jar:" + Services.io.newFileURI(do_get_file(path)).spec + "!/foo.txt"; var channel = NetUtil.newChannel({uri: spec, loadUsingSystemPrincipal: true}); - instr = channel.open(); - var val; + channel.open(); try { - val = channel.contentDisposition; + channel.contentDisposition; Assert.ok(false, "The channel has content disposition?!"); } catch (e) { // This is what we want to happen - there's no underlying channel, so no diff --git a/modules/libjar/test/unit/test_bug597702.js b/modules/libjar/test/unit/test_bug597702.js index b13fa936716d..5b4f17f2575b 100644 --- a/modules/libjar/test/unit/test_bug597702.js +++ b/modules/libjar/test/unit/test_bug597702.js @@ -2,31 +2,29 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); // Check that reading non existant inner jars results in the right error function run_test() { var file = do_get_file("data/test_bug597702.zip"); - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var outerJarBase = "jar:" + ios.newFileURI(file).spec + "!/"; + var outerJarBase = "jar:" + Services.io.newFileURI(file).spec + "!/"; var goodSpec = "jar:" + outerJarBase + "inner.jar!/hello"; var badSpec = "jar:" + outerJarBase + "jar_that_isnt_in_the.jar!/hello"; var goodChannel = NetUtil.newChannel({uri: goodSpec, loadUsingSystemPrincipal: true}); var badChannel = NetUtil.newChannel({uri: badSpec, loadUsingSystemPrincipal: true}); try { - instr = goodChannel.open(); + goodChannel.open(); } catch (e) { do_throw("Failed to open file in inner jar"); } try { - instr = badChannel.open(); + badChannel.open(); do_throw("Failed to report that file doesn't exist"); } catch (e) { Assert.ok(e.name == "NS_ERROR_FILE_NOT_FOUND"); } } - diff --git a/modules/libjar/test/unit/test_bug637286.js b/modules/libjar/test/unit/test_bug637286.js index 6f1e73eef419..b8113243848c 100644 --- a/modules/libjar/test/unit/test_bug637286.js +++ b/modules/libjar/test/unit/test_bug637286.js @@ -2,25 +2,23 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); // Check that the zip cache can expire entries from nested jars -var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); function open_inner_zip(base, idx) { - var spec = "jar:" + base + "inner" + idx + ".zip!/foo"; - var channel = NetUtil.newChannel({uri: spec, loadUsingSystemPrincipal: true}); - var stream = channel.open(); + var spec = "jar:" + base + "inner" + idx + ".zip!/foo"; + var channel = NetUtil.newChannel({uri: spec, loadUsingSystemPrincipal: true}); + channel.open(); } function run_test() { var file = do_get_file("data/test_bug637286.zip"); - var outerJarBase = "jar:" + ios.newFileURI(file).spec + "!/"; + var outerJarBase = "jar:" + Services.io.newFileURI(file).spec + "!/"; for (var i = 0; i < 40; i++) { open_inner_zip(outerJarBase, i); gc(); } } - diff --git a/modules/libjar/test/unit/test_bug658093.js b/modules/libjar/test/unit/test_bug658093.js index 918c65e2a0c9..ab7768fac4bd 100644 --- a/modules/libjar/test/unit/test_bug658093.js +++ b/modules/libjar/test/unit/test_bug658093.js @@ -2,19 +2,18 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); // Check that we don't crash on reading a directory entry signature -var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); function run_test() { var file = do_get_file("data/test_bug658093.zip"); - var spec = "jar:" + ios.newFileURI(file).spec + "!/0000"; + var spec = "jar:" + Services.io.newFileURI(file).spec + "!/0000"; var channel = NetUtil.newChannel({uri: spec, loadUsingSystemPrincipal: true}); var failed = false; try { - var stream = channel.open(); + channel.open(); } catch (e) { failed = true; } diff --git a/modules/libjar/test/unit/test_corrupt_1211262.js b/modules/libjar/test/unit/test_corrupt_1211262.js index 1b71f50f62b0..c410e71bb49a 100644 --- a/modules/libjar/test/unit/test_corrupt_1211262.js +++ b/modules/libjar/test/unit/test_corrupt_1211262.js @@ -8,15 +8,15 @@ function run_test() { var file = do_get_file("data/test_corrupt3.zip"); var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"]. - createInstance(Ci.nsIZipReader); + createInstance(Ci.nsIZipReader); zipreader.open(file); var failed = false; - for (let entryPath of zipreader.findEntries('*')) { + for (let entryPath of zipreader.findEntries("*")) { let entry = zipreader.getEntry(entryPath); if (!entry.isDirectory) { try { - let inputStream = zipreader.getInputStream(entryPath); + zipreader.getInputStream(entryPath); } catch (e) { failed = true; } diff --git a/modules/libjar/test/unit/test_corrupt_536911.js b/modules/libjar/test/unit/test_corrupt_536911.js index a0febb8f4f7e..d6e388807981 100644 --- a/modules/libjar/test/unit/test_corrupt_536911.js +++ b/modules/libjar/test/unit/test_corrupt_536911.js @@ -2,8 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function wrapInputStream(input) -{ +function wrapInputStream(input) { var nsIScriptableInputStream = Ci.nsIScriptableInputStream; var factory = Cc["@mozilla.org/scriptableinputstream;1"]; var wrapper = factory.createInstance(nsIScriptableInputStream); diff --git a/modules/libjar/test/unit/test_crx.js b/modules/libjar/test/unit/test_crx.js index 5e7ddb52efab..d644c4138dc3 100644 --- a/modules/libjar/test/unit/test_crx.js +++ b/modules/libjar/test/unit/test_crx.js @@ -4,8 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function wrapInputStream(input) -{ +function wrapInputStream(input) { let nsIScriptableInputStream = Ci.nsIScriptableInputStream; let factory = Cc["@mozilla.org/scriptableinputstream;1"]; let wrapper = factory.createInstance(nsIScriptableInputStream); @@ -20,17 +19,17 @@ function run_test() { let file = do_get_file("data/test_crx_dummy.crx"); let zipreader = Cc["@mozilla.org/libjar/zip-reader;1"]. - createInstance(Ci.nsIZipReader); + createInstance(Ci.nsIZipReader); zipreader.open(file); // do crc stuff function check_archive_crc() { zipreader.test(null); return true; } - Assert.ok(check_archive_crc()) - let entries = zipreader.findEntries(null); - let stream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/Makefile.in")) - let dirstream= wrapInputStream(zipreader.getInputStream("modules/libjar/test/")) + Assert.ok(check_archive_crc()); + zipreader.findEntries(null); + let stream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/Makefile.in")); + let dirstream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/")); zipreader.close(); zipreader = null; Cu.forceGC(); diff --git a/modules/libjar/test/unit/test_jarchannel.js b/modules/libjar/test/unit/test_jarchannel.js index c101f9d671f8..5d3aa575e2f2 100644 --- a/modules/libjar/test/unit/test_jarchannel.js +++ b/modules/libjar/test/unit/test_jarchannel.js @@ -7,21 +7,14 @@ */ -const {classes: Cc, - interfaces: Ci, - results: Cr, - utils: Cu, - Constructor: ctor - } = Components; +const {Constructor: ctor} = Components; +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); -const ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); -const dirSvc = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties); -const obs = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); +const ios = Services.io; +const dirSvc = Services.dirsvc; +const obs = Services.obs; const nsIBinaryInputStream = ctor("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", @@ -40,33 +33,27 @@ Listener.prototype = { gotStartRequest: false, available: -1, gotStopRequest: false, - QueryInterface: function(iid) { - if (iid.equals(Ci.nsISupports) || - iid.equals(Ci.nsIRequestObserver)) - return this; - throw Cr.NS_ERROR_NO_INTERFACE; - }, - onDataAvailable: function(request, ctx, stream, offset, count) { + QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver"]), + onDataAvailable(request, ctx, stream, offset, count) { try { this.available = stream.available(); Assert.equal(this.available, count); // Need to consume stream to avoid assertion new nsIBinaryInputStream(stream).readBytes(count); - } - catch (ex) { + } catch (ex) { do_throw(ex); } }, - onStartRequest: function(request, ctx) { + onStartRequest(request, ctx) { this.gotStartRequest = true; }, - onStopRequest: function(request, ctx, status) { + onStopRequest(request, ctx, status) { this.gotStopRequest = true; Assert.equal(status, 0); if (this._callback) { this._callback.call(null, this); } - } + }, }; /** @@ -74,7 +61,7 @@ Listener.prototype = { */ function testAsync() { var uri = jarBase + "/inner40.zip"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); Assert.ok(chan.contentLength < 0); chan.asyncOpen(new Listener(function(l) { Assert.ok(chan.contentLength > 0); @@ -94,13 +81,13 @@ add_test(testAsync); * Basic test for nsIZipReader. */ function testZipEntry() { - var uri = jarBase + "/inner40.zip"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}) - .QueryInterface(Ci.nsIJARChannel); - var entry = chan.zipEntry; - Assert.ok(entry.CRC32 == 0x8b635486); - Assert.ok(entry.realSize == 184); - run_next_test(); + var uri = jarBase + "/inner40.zip"; + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}) + .QueryInterface(Ci.nsIJARChannel); + var entry = chan.zipEntry; + Assert.ok(entry.CRC32 == 0x8b635486); + Assert.ok(entry.realSize == 184); + run_next_test(); } add_test(testZipEntry); @@ -111,7 +98,7 @@ add_test(testZipEntry); */ add_test(function testSync() { var uri = jarBase + "/inner40.zip"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); var stream = chan.open(); Assert.ok(chan.contentLength > 0); Assert.equal(stream.available(), chan.contentLength); @@ -127,7 +114,7 @@ add_test(function testSync() { */ add_test(function testSyncNested() { var uri = "jar:" + jarBase + "/inner40.zip!/foo"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); var stream = chan.open(); Assert.ok(chan.contentLength > 0); Assert.equal(stream.available(), chan.contentLength); @@ -142,7 +129,7 @@ add_test(function testSyncNested() { */ add_test(function testAsyncNested(next) { var uri = "jar:" + jarBase + "/inner40.zip!/foo"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); chan.asyncOpen(new Listener(function(l) { Assert.ok(chan.contentLength > 0); Assert.ok(l.gotStartRequest); @@ -162,7 +149,7 @@ add_test(function testSyncCloseUnlocks() { copy.append(fileBase); file.copyTo(copy.parent, copy.leafName); var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); var stream = chan.open(); Assert.ok(chan.contentLength > 0); stream.close(); @@ -172,8 +159,7 @@ add_test(function testSyncCloseUnlocks() { try { copy.remove(false); - } - catch (ex) { + } catch (ex) { do_throw(ex); } @@ -190,9 +176,9 @@ add_test(function testAsyncCloseUnlocks() { file.copyTo(copy.parent, copy.leafName); var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; - var chan = NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true}); + var chan = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); - chan.asyncOpen(new Listener(function (l) { + chan.asyncOpen(new Listener(function(l) { Assert.ok(chan.contentLength > 0); // Drop any jar caches @@ -200,8 +186,7 @@ add_test(function testAsyncCloseUnlocks() { try { copy.remove(false); - } - catch (ex) { + } catch (ex) { do_throw(ex); } diff --git a/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js b/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js index b679b4ecf2bb..fb7c6308f685 100644 --- a/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js +++ b/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js @@ -4,8 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function wrapInputStream(input) -{ +function wrapInputStream(input) { var nsIScriptableInputStream = Ci.nsIScriptableInputStream; var factory = Cc["@mozilla.org/scriptableinputstream;1"]; var wrapper = factory.createInstance(nsIScriptableInputStream); @@ -19,17 +18,17 @@ function run_test() { var file = do_get_file("data/test_bug333423.zip"); var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"]. - createInstance(Ci.nsIZipReader); + createInstance(Ci.nsIZipReader); zipreader.open(file); // do crc stuff function check_archive_crc() { zipreader.test(null); return true; } - Assert.ok(check_archive_crc()) - var entries = zipreader.findEntries(null); - var stream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/Makefile.in")) - var dirstream= wrapInputStream(zipreader.getInputStream("modules/libjar/test/")) + Assert.ok(check_archive_crc()); + zipreader.findEntries(null); + var stream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/Makefile.in")); + var dirstream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/")); zipreader.close(); zipreader = null; Cu.forceGC(); diff --git a/modules/libjar/test/unit/test_not_found.js b/modules/libjar/test/unit/test_not_found.js index af6df8b03689..4a29459e1d1d 100644 --- a/modules/libjar/test/unit/test_not_found.js +++ b/modules/libjar/test/unit/test_not_found.js @@ -1,20 +1,19 @@ // Should report file not found on non-existent files +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); const path = "data/test_bug333423.zip"; function run_test() { - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - var spec = "jar:" + ios.newFileURI(do_get_file(path)).spec + "!/"; + var spec = "jar:" + Services.io.newFileURI(do_get_file(path)).spec + "!/"; var channel = NetUtil.newChannel({ uri: spec + "file_that_isnt_in.archive", - loadUsingSystemPrincipal: true + loadUsingSystemPrincipal: true, }); try { - instr = channel.open(); - do_throw("Failed to report that file doesn't exist") + channel.open(); + do_throw("Failed to report that file doesn't exist"); } catch (e) { - Assert.ok(e.name == "NS_ERROR_FILE_NOT_FOUND") + Assert.ok(e.name == "NS_ERROR_FILE_NOT_FOUND"); } } diff --git a/modules/libjar/test/unit/test_umlaute.js b/modules/libjar/test/unit/test_umlaute.js index 329c336da30f..6f19e7b341d5 100644 --- a/modules/libjar/test/unit/test_umlaute.js +++ b/modules/libjar/test/unit/test_umlaute.js @@ -1,7 +1,7 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); function run_test() { - var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); - var tmpDir = dirService.get("TmpD", Ci.nsIFile); + var tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile); var zipfile = do_get_file("data/test_umlaute.zip"); @@ -15,7 +15,7 @@ function run_test() { zipreader.open(zipfile); var entries = zipreader.findEntries(null); - Assert.ok(entries.hasMore()); + Assert.ok(entries.hasMore()); var entryName = entries.getNext(); Assert.equal(entryName, "test_\u00FC.txt"); diff --git a/modules/libjar/zipwriter/test/unit/head_zipwriter.js b/modules/libjar/zipwriter/test/unit/head_zipwriter.js index 36e2626992dd..6e9238ae352a 100644 --- a/modules/libjar/zipwriter/test/unit/head_zipwriter.js +++ b/modules/libjar/zipwriter/test/unit/head_zipwriter.js @@ -5,20 +5,20 @@ const NS_ERROR_IN_PROGRESS = 2152398863; -const PR_RDONLY = 0x01 -const PR_WRONLY = 0x02 -const PR_RDWR = 0x04 -const PR_CREATE_FILE = 0x08 -const PR_APPEND = 0x10 -const PR_TRUNCATE = 0x20 -const PR_SYNC = 0x40 -const PR_EXCL = 0x80 +const PR_RDONLY = 0x01; +const PR_WRONLY = 0x02; +const PR_RDWR = 0x04; +const PR_CREATE_FILE = 0x08; +const PR_APPEND = 0x10; +const PR_TRUNCATE = 0x20; +const PR_SYNC = 0x40; +const PR_EXCL = 0x80; const ZIP_EOCDR_HEADER_SIZE = 22; const ZIP_FILE_HEADER_SIZE = 30; const ZIP_CDS_HEADER_SIZE = 46; -const ZIP_METHOD_STORE = 0 -const ZIP_METHOD_DEFLATE = 8 +const ZIP_METHOD_STORE = 0; +const ZIP_METHOD_DEFLATE = 8; const ZIP_EXTENDED_TIMESTAMP_SIZE = 9; const PR_USEC_PER_MSEC = 1000; @@ -27,13 +27,13 @@ const PR_MSEC_PER_SEC = 1000; const DATA_DIR = "data/"; -var ioSvc = Cc["@mozilla.org/network/io-service;1"] - .getService(Ci.nsIIOService); +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); +var ioSvc = Services.io; var ZipWriter = Components.Constructor("@mozilla.org/zipwriter;1", - "nsIZipWriter"); + "nsIZipWriter"); var ZipReader = Components.Constructor("@mozilla.org/libjar/zip-reader;1", - "nsIZipReader", "open"); + "nsIZipReader", "open"); var tmpDir = do_get_profile(); var tmpFile = tmpDir.clone(); diff --git a/modules/libjar/zipwriter/test/unit/test_alignment.js b/modules/libjar/zipwriter/test/unit/test_alignment.js index f757a93b51e5..a82ab5e3b14b 100644 --- a/modules/libjar/zipwriter/test/unit/test_alignment.js +++ b/modules/libjar/zipwriter/test/unit/test_alignment.js @@ -11,44 +11,40 @@ const time = 1199145600000; // Jan 1st 2008 var TESTS = [ { name: "test.txt", - compression: Ci.nsIZipWriter.COMPRESSION_DEFAULT + compression: Ci.nsIZipWriter.COMPRESSION_DEFAULT, }, { name: "test.png", - compression: Ci.nsIZipWriter.COMPRESSION_NONE - } + compression: Ci.nsIZipWriter.COMPRESSION_NONE, + }, ]; -function swap16(n) -{ - return (((n >> 8) & 0xFF) << 0) | - (((n >> 0) & 0xFF) << 8); +function swap16(n) { + return (((n >> 8) & 0xFF) << 0) | + (((n >> 0) & 0xFF) << 8); } -function swap32(n) -{ - return (((n >> 24) & 0xFF) << 0) | - (((n >> 16) & 0xFF) << 8) | - (((n >> 8) & 0xFF) << 16) | - (((n >> 0) & 0xFF) << 24); +function swap32(n) { + return (((n >> 24) & 0xFF) << 0) | + (((n >> 16) & 0xFF) << 8) | + (((n >> 8) & 0xFF) << 16) | + (((n >> 0) & 0xFF) << 24); } -function move_to_data(bis, offset) -{ +function move_to_data(bis, offset) { bis.readBytes(18); // Move to compressed size var size = swap32(bis.read32()); bis.readBytes(4); var file_len = swap16(bis.read16()); var extra_len = swap16(bis.read16()); - var file = bis.readBytes(file_len); + bis.readBytes(file_len); bis.readBytes(extra_len); offset += ZIP_FILE_HEADER_SIZE + file_len + extra_len; - return {offset: offset, size: size}; + return {offset, size}; } -function test_alignment(align_size) -{ +function test_alignment(align_size) { // Create zip for testing. zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); for (var i = 0; i < TESTS.length; i++) { @@ -56,17 +52,17 @@ function test_alignment(align_size) zipW.addEntryFile(TESTS[i].name, TESTS[i].compression, source, false); } var stream = Cc["@mozilla.org/io/string-input-stream;1"] - .createInstance(Ci.nsIStringInputStream); + .createInstance(Ci.nsIStringInputStream); stream.setData(DATA, DATA.length); zipW.addEntryStream(FILENAME, time * PR_USEC_PER_MSEC, - Ci.nsIZipWriter.COMPRESSION_NONE, stream, false); + Ci.nsIZipWriter.COMPRESSION_NONE, stream, false); zipW.alignStoredFiles(align_size); zipW.close(); // Check data can be decompressed. var zipR = new ZipReader(tmpFile); - var stream = Cc["@mozilla.org/scriptableinputstream;1"] - .createInstance(Ci.nsIScriptableInputStream); + stream = Cc["@mozilla.org/scriptableinputstream;1"] + .createInstance(Ci.nsIScriptableInputStream); stream.init(zipR.getInputStream(FILENAME)); var result = stream.read(DATA.length); Assert.equal(result, DATA); @@ -75,10 +71,10 @@ function test_alignment(align_size) // Check data is correct and aligned. var fis = Cc["@mozilla.org/network/file-input-stream;1"] - .createInstance(Ci.nsIFileInputStream); + .createInstance(Ci.nsIFileInputStream); fis.init(tmpFile, -1, -1, null); let bis = Cc["@mozilla.org/binaryinputstream;1"] - .createInstance(Ci.nsIBinaryInputStream); + .createInstance(Ci.nsIBinaryInputStream); bis.setInputStream(fis); var offset = 0; @@ -95,7 +91,7 @@ function test_alignment(align_size) ret = move_to_data(bis, offset); // "test_data.txt" offset = ret.offset; - var result = bis.readBytes(DATA.length); + result = bis.readBytes(DATA.length); Assert.equal(result, DATA); Assert.equal(offset % align_size, 0); @@ -103,8 +99,7 @@ function test_alignment(align_size) bis.close(); } -function run_test() -{ +function run_test() { test_alignment(2); test_alignment(4); test_alignment(16); diff --git a/modules/libjar/zipwriter/test/unit/test_asyncadd.js b/modules/libjar/zipwriter/test/unit/test_asyncadd.js index 71cef1bc3e65..a0be322ed31b 100644 --- a/modules/libjar/zipwriter/test/unit/test_asyncadd.js +++ b/modules/libjar/zipwriter/test/unit/test_asyncadd.js @@ -10,24 +10,22 @@ var TESTS = [ { name: "test.txt", size: 232, - crc: 0x0373ac26 + crc: 0x0373ac26, }, { name: "test.png", size: 3402, - crc: 0x504a5c30 - } + crc: 0x504a5c30, + }, ]; var size = 0; var observer = { - onStartRequest: function(request, context) - { + onStartRequest(request, context) { }, - onStopRequest: function(request, context, status) - { + onStopRequest(request, context, status) { Assert.equal(status, Cr.NS_OK); zipW.close(); @@ -57,47 +55,43 @@ var observer = { zipR.close(); do_test_finished(); - } + }, }; var methods = { - file: function method_file(entry, source) - { + file: function method_file(entry, source) { zipW.addEntryFile(entry, Ci.nsIZipWriter.COMPRESSION_NONE, source, true); }, - channel: function method_channel(entry, source) - { + channel: function method_channel(entry, source) { zipW.addEntryChannel(entry, source.lastModifiedTime * PR_MSEC_PER_SEC, Ci.nsIZipWriter.COMPRESSION_NONE, NetUtil.newChannel({ uri: ioSvc.newFileURI(source), - loadUsingSystemPrincipal: true + loadUsingSystemPrincipal: true, }), true); }, - stream: function method_stream(entry, source) - { + stream: function method_stream(entry, source) { zipW.addEntryStream(entry, source.lastModifiedTime * PR_MSEC_PER_SEC, Ci.nsIZipWriter.COMPRESSION_NONE, NetUtil.newChannel({ uri: ioSvc.newFileURI(source), - loadUsingSystemPrincipal: true + loadUsingSystemPrincipal: true, }).open(), true); - } -} + }, +}; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); for (var i = 0; i < TESTS.length; i++) { - var source = do_get_file(DATA_DIR+TESTS[i].name); + var source = do_get_file(DATA_DIR + TESTS[i].name); for (let method in methods) { var entry = method + "/" + TESTS[i].name; methods[method](entry, source); size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE + (ZIP_EXTENDED_TIMESTAMP_SIZE * 2) + - (entry.length*2) + TESTS[i].size; + (entry.length * 2) + TESTS[i].size; } } do_test_pending(); diff --git a/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js b/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js index 852ca258fe46..20aec202d5c9 100644 --- a/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js +++ b/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js @@ -6,21 +6,18 @@ const FILENAME = "missing.txt"; var observer = { - onStartRequest: function(request, context) - { + onStartRequest(request, context) { }, - onStopRequest: function(request, context, status) - { + onStopRequest(request, context, status) { Assert.equal(status, Cr.NS_ERROR_FILE_NOT_FOUND); zipW.close(); Assert.equal(ZIP_EOCDR_HEADER_SIZE, tmpFile.fileSize); do_test_finished(); - } + }, }; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); var source = tmpDir.clone(); diff --git a/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js b/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js index ce09dd6a2cd3..6f986fa5fe0e 100644 --- a/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js +++ b/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js @@ -6,21 +6,18 @@ const FILENAME = "missing.txt"; var observer = { - onStartRequest: function(request, context) - { + onStartRequest(request, context) { }, - onStopRequest: function(request, context, status) - { + onStopRequest(request, context, status) { Assert.equal(status, Cr.NS_ERROR_FILE_NOT_FOUND); zipW.close(); Assert.equal(ZIP_EOCDR_HEADER_SIZE, tmpFile.fileSize); do_test_finished(); - } + }, }; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); zipW.removeEntry(FILENAME, true); do_test_pending(); diff --git a/modules/libjar/zipwriter/test/unit/test_asyncremove.js b/modules/libjar/zipwriter/test/unit/test_asyncremove.js index 11eca872526b..253f7dd328eb 100644 --- a/modules/libjar/zipwriter/test/unit/test_asyncremove.js +++ b/modules/libjar/zipwriter/test/unit/test_asyncremove.js @@ -5,16 +5,14 @@ var TESTS = [ "test.txt", - "test.png" + "test.png", ]; var observer = { - onStartRequest: function(request, context) - { + onStartRequest(request, context) { }, - onStopRequest: function(request, context, status) - { + onStopRequest(request, context, status) { Assert.equal(status, Cr.NS_OK); zipW.close(); @@ -23,11 +21,10 @@ var observer = { var newTmpFile = tmpFile.clone(); Assert.equal(newTmpFile.fileSize, ZIP_EOCDR_HEADER_SIZE); do_test_finished(); - } + }, }; -function run_test() -{ +function run_test() { // Copy our test zip to the tmp dir so we can modify it var testzip = do_get_file(DATA_DIR + "test.zip"); testzip.copyTo(tmpDir, tmpFile.leafName); diff --git a/modules/libjar/zipwriter/test/unit/test_bug399727.js b/modules/libjar/zipwriter/test/unit/test_bug399727.js index 7eb02a605b9a..d30c2308bbe0 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug399727.js +++ b/modules/libjar/zipwriter/test/unit/test_bug399727.js @@ -21,17 +21,17 @@ BinaryComparer.prototype = { length: null, callback: null, - onStartRequest: function(aRequest, aContext) { + onStartRequest(aRequest, aContext) { }, - onStopRequest: function(aRequest, aContext, aStatusCode) { + onStopRequest(aRequest, aContext, aStatusCode) { this.fileStream.close(); Assert.equal(aStatusCode, Cr.NS_OK); Assert.equal(this.offset, this.length); this.callback(); }, - onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { + onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) { var stream = Cc["@mozilla.org/binaryinputstream;1"]. createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(aInputStream); @@ -39,34 +39,30 @@ BinaryComparer.prototype = { for (var i = 0; i < aCount; i++) { try { source = this.fileStream.read8(); - } - catch (e) { + } catch (e) { do_throw("Unable to read from file at offset " + this.offset + " " + e); } try { actual = stream.read8(); - } - catch (e) { + } catch (e) { do_throw("Unable to read from converted stream at offset " + this.offset + " " + e); } if (source != actual) do_throw("Invalid value " + actual + " at offset " + this.offset + ", should have been " + source); this.offset++; } - } -} + }, +}; -function comparer_callback() -{ +function comparer_callback() { do_test_finished(); } -function run_test() -{ +function run_test() { var source = do_get_file(DATA_DIR + "test_bug399727.html"); var comparer = new BinaryComparer(do_get_file(DATA_DIR + "test_bug399727.zlib"), comparer_callback); - + // Prepare the stream converter var scs = Cc["@mozilla.org/streamConverters;1"]. getService(Ci.nsIStreamConverterService); diff --git a/modules/libjar/zipwriter/test/unit/test_bug419769_1.js b/modules/libjar/zipwriter/test/unit/test_bug419769_1.js index 26251cc6fd53..62ff75405bbc 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug419769_1.js +++ b/modules/libjar/zipwriter/test/unit/test_bug419769_1.js @@ -9,8 +9,7 @@ const CRC = 0x00000000; // XXX Must use a constant time here away from DST changes. See bug 402434. const time = 1199145600000; // Jan 1st 2008 -function testpass(source) -{ +function testpass(source) { // Should exist. Assert.ok(source.hasEntry(FILENAME)); @@ -31,8 +30,7 @@ function testpass(source) Assert.equal(entry.CRC32, CRC); } -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); // Shouldn't be there to start with. @@ -41,10 +39,10 @@ function run_test() Assert.ok(!zipW.inQueue); var stream = Cc["@mozilla.org/io/string-input-stream;1"] - .createInstance(Ci.nsIStringInputStream); + .createInstance(Ci.nsIStringInputStream); stream.setData(DATA, DATA.length); zipW.addEntryStream(FILENAME, time * PR_USEC_PER_MSEC, - Ci.nsIZipWriter.COMPRESSION_BEST, stream, false); + Ci.nsIZipWriter.COMPRESSION_BEST, stream, false); // Check that zip state is right at this stage. testpass(zipW); @@ -59,8 +57,8 @@ function run_test() var zipR = new ZipReader(tmpFile); testpass(zipR); zipR.test(FILENAME); - var stream = Cc["@mozilla.org/scriptableinputstream;1"] - .createInstance(Ci.nsIScriptableInputStream); + stream = Cc["@mozilla.org/scriptableinputstream;1"] + .createInstance(Ci.nsIScriptableInputStream); stream.init(zipR.getInputStream(FILENAME)); var result = stream.read(DATA.length); stream.close(); diff --git a/modules/libjar/zipwriter/test/unit/test_bug419769_2.js b/modules/libjar/zipwriter/test/unit/test_bug419769_2.js index b1e4977cedaa..8133b11d061b 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug419769_2.js +++ b/modules/libjar/zipwriter/test/unit/test_bug419769_2.js @@ -8,8 +8,7 @@ const FILENAME = "test.txt"; const CRC = 0x00000000; const time = Date.now(); -function testpass(source) -{ +function testpass(source) { // Should exist. Assert.ok(source.hasEntry(FILENAME)); @@ -28,8 +27,7 @@ function testpass(source) Assert.equal(entry.CRC32, CRC); } -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); // Shouldn't be there to start with. diff --git a/modules/libjar/zipwriter/test/unit/test_bug425768.js b/modules/libjar/zipwriter/test/unit/test_bug425768.js index d5ca1d98e910..306706b1c1e5 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug425768.js +++ b/modules/libjar/zipwriter/test/unit/test_bug425768.js @@ -6,8 +6,7 @@ const DIRNAME = "test/"; const time = Date.now(); -function run_test() -{ +function run_test() { // Copy in the test file. var source = do_get_file("data/test.zip"); source.copyTo(tmpFile.parent, tmpFile.leafName); diff --git a/modules/libjar/zipwriter/test/unit/test_bug433248.js b/modules/libjar/zipwriter/test/unit/test_bug433248.js index aee024c7ba55..5b3996282bba 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug433248.js +++ b/modules/libjar/zipwriter/test/unit/test_bug433248.js @@ -3,71 +3,61 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function run_test() -{ - var test; +function run_test() { // zipW is an uninitialised zipwriter at this point. try { - test = zipW.file; + zipW.file; do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { - test = zipW.comment; + zipW.comment; do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.comment = "test"; do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.addEntryDirectory("test", 0, false); do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.addEntryFile("test", Ci.nsIZipWriter.COMPRESSION_DEFAULT, tmpDir, false); do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.removeEntry("test", false); do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.processQueue(null, null); do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } try { zipW.close(); do_throw("Should have thrown uninitialized error."); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_NOT_INITIALIZED); } } diff --git a/modules/libjar/zipwriter/test/unit/test_bug446708.js b/modules/libjar/zipwriter/test/unit/test_bug446708.js index ea83f327632e..46f72dfd11b0 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug446708.js +++ b/modules/libjar/zipwriter/test/unit/test_bug446708.js @@ -5,17 +5,16 @@ function run_test() { } // Add |file| to the zip. |path| is the current path for the file. -function AddToZip(zipWriter, path, file) -{ +function AddToZip(zipWriter, path, file) { var currentPath = path + file.leafName; - + if (file.isDirectory()) { currentPath += "/"; } - + // THIS IS WHERE THE ERROR OCCURS, FOR THE FILE "st14-1.tiff" IN "test_bug446708" zipWriter.addEntryFile(currentPath, Ci.nsIZipWriter.COMPRESSION_DEFAULT, file, false); - + // if it's a dir, continue adding its contents recursively... if (file.isDirectory()) { var entries = file.QueryInterface(Ci.nsIFile).directoryEntries; @@ -24,14 +23,13 @@ function AddToZip(zipWriter, path, file) AddToZip(zipWriter, currentPath, entry); } } - + // ...otherwise, we're done } -function RecursivelyZipDirectory(bundle) -{ +function RecursivelyZipDirectory(bundle) { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); - AddToZip(zipW, "", bundle); + AddToZip(zipW, "", bundle); zipW.close(); } diff --git a/modules/libjar/zipwriter/test/unit/test_bug467740.js b/modules/libjar/zipwriter/test/unit/test_bug467740.js index 89f011856397..9a2de8e4ec34 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug467740.js +++ b/modules/libjar/zipwriter/test/unit/test_bug467740.js @@ -3,8 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function run_test() -{ +function run_test() { // In this test we try to open some files that aren't archives: // - An empty file, that is certainly not an archive. // - A file that couldn't be mistaken for archive, since it is too small. diff --git a/modules/libjar/zipwriter/test/unit/test_bug717061.js b/modules/libjar/zipwriter/test/unit/test_bug717061.js index 5f8a1b9dc634..d024841a6912 100644 --- a/modules/libjar/zipwriter/test/unit/test_bug717061.js +++ b/modules/libjar/zipwriter/test/unit/test_bug717061.js @@ -4,11 +4,11 @@ function BinaryComparer(file, callback) { var fstream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); + createInstance(Ci.nsIFileInputStream); fstream.init(file, -1, 0, 0); this.length = file.fileSize; this.fileStream = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); + createInstance(Ci.nsIBinaryInputStream); this.fileStream.setInputStream(fstream); this.offset = 0; this.callback = callback; @@ -20,72 +20,69 @@ BinaryComparer.prototype = { length: null, callback: null, - onStartRequest: function(aRequest, aContext) { + onStartRequest(aRequest, aContext) { }, - onStopRequest: function(aRequest, aContext, aStatusCode) { + onStopRequest(aRequest, aContext, aStatusCode) { this.fileStream.close(); Assert.equal(aStatusCode, Cr.NS_OK); Assert.equal(this.offset, this.length); this.callback(); }, - onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { + onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) { var stream = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); + createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(aInputStream); var source, actual; for (var i = 0; i < aCount; i++) { try { source = this.fileStream.read8(); - } - catch (e) { + } catch (e) { do_throw("Unable to read from file at offset " + this.offset + " " + e); } try { actual = stream.read8(); - } - catch (e) { - do_throw("Unable to read from converted stream at offset " + this.offset + " " + e); + } catch (e) { + do_throw("Unable to read from converted stream at offset " + + this.offset + " " + e); } // The byte at offset 9 is the OS byte (see RFC 1952, section 2.3), which // can legitimately differ when the source is compressed on different // operating systems. The actual .gz for this test was created on a Unix // system, but we want the test to work correctly everywhere. So ignore // the byte at offset 9. - if (this.offset == 9) - ; - else if (source != actual) - do_throw("Invalid value " + actual + " at offset " + this.offset + ", should have been " + source); + if (this.offset != 9 && source != actual) { + do_throw("Invalid value " + actual + " at offset " + + this.offset + ", should have been " + source); + } this.offset++; } - } -} + }, +}; -function comparer_callback() -{ +function comparer_callback() { do_test_finished(); } -function run_test() -{ +function run_test() { var source = do_get_file(DATA_DIR + "test_bug717061.html"); var comparer = new BinaryComparer(do_get_file(DATA_DIR + "test_bug717061.gz"), - comparer_callback); - + comparer_callback); + // Prepare the stream converter var scs = Cc["@mozilla.org/streamConverters;1"]. - getService(Ci.nsIStreamConverterService); + getService(Ci.nsIStreamConverterService); var converter = scs.asyncConvertData("uncompressed", "gzip", comparer, null); // Open the expected output file var fstream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); + createInstance(Ci.nsIFileInputStream); fstream.init(source, -1, 0, 0); // Set up a pump to push data from the file to the stream converter var pump = Cc["@mozilla.org/network/input-stream-pump;1"]. - createInstance(Ci.nsIInputStreamPump); + createInstance(Ci.nsIInputStreamPump); pump.init(fstream, 0, 0, true); pump.asyncRead(converter, null); do_test_pending(); diff --git a/modules/libjar/zipwriter/test/unit/test_createempty.js b/modules/libjar/zipwriter/test/unit/test_createempty.js index 8fc2dddde5b0..464c3b243f49 100644 --- a/modules/libjar/zipwriter/test/unit/test_createempty.js +++ b/modules/libjar/zipwriter/test/unit/test_createempty.js @@ -3,8 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); zipW.close(); diff --git a/modules/libjar/zipwriter/test/unit/test_deflatedata.js b/modules/libjar/zipwriter/test/unit/test_deflatedata.js index e7b6479b0551..f9d79cdb14ae 100644 --- a/modules/libjar/zipwriter/test/unit/test_deflatedata.js +++ b/modules/libjar/zipwriter/test/unit/test_deflatedata.js @@ -9,8 +9,7 @@ const CRC = 0xe6164331; // XXX Must use a constant time here away from DST changes. See bug 402434. const time = 1199145600000; // Jan 1st 2008 -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); // Shouldn't be there to start with. @@ -42,7 +41,7 @@ function run_test() zipR.test(FILENAME); - var stream = Cc["@mozilla.org/scriptableinputstream;1"] + stream = Cc["@mozilla.org/scriptableinputstream;1"] .createInstance(Ci.nsIScriptableInputStream); stream.init(zipR.getInputStream(FILENAME)); var result = stream.read(DATA.length); diff --git a/modules/libjar/zipwriter/test/unit/test_directory.js b/modules/libjar/zipwriter/test/unit/test_directory.js index 3f4151ac73da..70e93bbf08c8 100644 --- a/modules/libjar/zipwriter/test/unit/test_directory.js +++ b/modules/libjar/zipwriter/test/unit/test_directory.js @@ -8,8 +8,7 @@ const DIRNAME1_CORRECT = "test/"; const DIRNAME2 = "test2/"; const time = Date.now(); -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); zipW.addEntryDirectory(DIRNAME1, time * PR_USEC_PER_MSEC, false); diff --git a/modules/libjar/zipwriter/test/unit/test_editexisting.js b/modules/libjar/zipwriter/test/unit/test_editexisting.js index b1854b7b4dd7..c58447260e1c 100644 --- a/modules/libjar/zipwriter/test/unit/test_editexisting.js +++ b/modules/libjar/zipwriter/test/unit/test_editexisting.js @@ -9,19 +9,18 @@ var TESTS = [ name: "test.txt", size: 232, crc: 0x0373ac26, - time: Date.UTC(2007, 4, 1, 20, 44, 55) + time: Date.UTC(2007, 4, 1, 20, 44, 55), }, { name: "test.png", size: 3402, crc: 0x504a5c30, - time: Date.UTC(2007, 4, 1, 20, 49, 39) - } + time: Date.UTC(2007, 4, 1, 20, 49, 39), + }, ]; var BADENTRY = "unknown.txt"; -function run_test() -{ +function run_test() { // Copy our test zip to the tmp dir so we can modify it var testzip = do_get_file(DATA_DIR + "test.zip"); testzip.copyTo(tmpDir, tmpFile.leafName); @@ -30,7 +29,7 @@ function run_test() zipW.open(tmpFile, PR_RDWR); - for (var i = 0; i < TESTS.length; i++) { + for (let i = 0; i < TESTS.length; i++) { Assert.ok(zipW.hasEntry(TESTS[i].name)); var entry = zipW.getEntry(TESTS[i].name); Assert.ok(entry != null); @@ -43,12 +42,11 @@ function run_test() try { zipW.removeEntry(BADENTRY, false); do_throw("shouldn't be able to remove an entry that doesn't exist"); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_FILE_NOT_FOUND); } - for (var i = 0; i < TESTS.length; i++) { + for (let i = 0; i < TESTS.length; i++) { zipW.removeEntry(TESTS[i].name, false); } diff --git a/modules/libjar/zipwriter/test/unit/test_storedata.js b/modules/libjar/zipwriter/test/unit/test_storedata.js index 16c0181bf345..c8c03fb4fd18 100644 --- a/modules/libjar/zipwriter/test/unit/test_storedata.js +++ b/modules/libjar/zipwriter/test/unit/test_storedata.js @@ -10,8 +10,7 @@ const CRC = 0xe6164331; // XXX Must use a constant time here away from DST changes. See bug 402434. const time = 1199145600000; // Jan 1st 2008 -function testpass(source) -{ +function testpass(source) { // Should exist. Assert.ok(source.hasEntry(FILENAME)); @@ -34,8 +33,7 @@ function testpass(source) Assert.equal(entry.CRC32, CRC); } -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); // Shouldn't be there to start with. @@ -67,7 +65,7 @@ function run_test() var zipR = new ZipReader(tmpFile); testpass(zipR); zipR.test(FILENAME); - var stream = Cc["@mozilla.org/scriptableinputstream;1"] + stream = Cc["@mozilla.org/scriptableinputstream;1"] .createInstance(Ci.nsIScriptableInputStream); stream.init(zipR.getInputStream(FILENAME)); var result = stream.read(DATA.length); diff --git a/modules/libjar/zipwriter/test/unit/test_sync.js b/modules/libjar/zipwriter/test/unit/test_sync.js index 94814f1307de..82ffa430fe3b 100644 --- a/modules/libjar/zipwriter/test/unit/test_sync.js +++ b/modules/libjar/zipwriter/test/unit/test_sync.js @@ -8,27 +8,26 @@ var TESTS = [ { name: "test.txt", size: 232, - crc: 0x0373ac26 + crc: 0x0373ac26, }, { name: "test.png", size: 3402, - crc: 0x504a5c30 - } + crc: 0x504a5c30, + }, ]; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); var size = 0; - for (var i = 0; i < TESTS.length; i++) { - var source = do_get_file(DATA_DIR + TESTS[i].name); + for (let i = 0; i < TESTS.length; i++) { + let source = do_get_file(DATA_DIR + TESTS[i].name); zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source, false); size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE + (ZIP_EXTENDED_TIMESTAMP_SIZE * 2) + - (TESTS[i].name.length*2) + TESTS[i].size; + (TESTS[i].name.length * 2) + TESTS[i].size; } zipW.close(); @@ -39,8 +38,8 @@ function run_test() // Test the stored data with the zipreader var zipR = new ZipReader(tmpFile); - for (var i = 0; i < TESTS.length; i++) { - var source = do_get_file(DATA_DIR + TESTS[i].name); + for (let i = 0; i < TESTS.length; i++) { + let source = do_get_file(DATA_DIR + TESTS[i].name); Assert.ok(zipR.hasEntry(TESTS[i].name)); var entry = zipR.getEntry(TESTS[i].name); diff --git a/modules/libjar/zipwriter/test/unit/test_undochange.js b/modules/libjar/zipwriter/test/unit/test_undochange.js index 972e1884a78a..0a2cd8c83d2a 100644 --- a/modules/libjar/zipwriter/test/unit/test_undochange.js +++ b/modules/libjar/zipwriter/test/unit/test_undochange.js @@ -6,31 +6,29 @@ // Values taken from using zipinfo to list the test.zip contents var TESTS = [ "test.txt", - "test.png" + "test.png", ]; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); - for (var i = 0; i < TESTS.length; i++) { - var source = do_get_file(DATA_DIR + TESTS[i]); + for (let i = 0; i < TESTS.length; i++) { + let source = do_get_file(DATA_DIR + TESTS[i]); zipW.addEntryFile(TESTS[i], Ci.nsIZipWriter.COMPRESSION_NONE, source, false); } try { - var source = do_get_file(DATA_DIR + TESTS[0]); + let source = do_get_file(DATA_DIR + TESTS[0]); zipW.addEntryFile(TESTS[0], Ci.nsIZipWriter.COMPRESSION_NONE, source, false); do_throw("Should not be able to add the same file twice"); - } - catch (e) { + } catch (e) { Assert.equal(e.result, Cr.NS_ERROR_FILE_ALREADY_EXISTS); } // Remove all the tests and see if we are left with an empty zip - for (var i = 0; i < TESTS.length; i++) { + for (let i = 0; i < TESTS.length; i++) { zipW.removeEntry(TESTS[i], false); } diff --git a/modules/libjar/zipwriter/test/unit/test_zipcomment.js b/modules/libjar/zipwriter/test/unit/test_zipcomment.js index 5553894d7289..afe0fd78864c 100644 --- a/modules/libjar/zipwriter/test/unit/test_zipcomment.js +++ b/modules/libjar/zipwriter/test/unit/test_zipcomment.js @@ -6,8 +6,7 @@ const DATA = "ZIP WRITER TEST COMMENT"; const DATA2 = "ANOTHER ONE"; -function run_test() -{ +function run_test() { zipW.open(tmpFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); zipW.comment = DATA; zipW.close(); diff --git a/modules/libjar/zipwriter/test/unit/test_zippermissions.js b/modules/libjar/zipwriter/test/unit/test_zippermissions.js index 000362e66e88..15112daa327a 100644 --- a/modules/libjar/zipwriter/test/unit/test_zippermissions.js +++ b/modules/libjar/zipwriter/test/unit/test_zippermissions.js @@ -16,7 +16,7 @@ function build_tests() { for (let o = 0; o <= 7; o++) { TESTS[id] = { name: "test" + u + g + o, - permission: (u << 6) + (g << 3) + o + permission: (u << 6) + (g << 3) + o, }; id++; } diff --git a/modules/libmar/tests/unit/test_create.js b/modules/libmar/tests/unit/test_create.js index b0b7be62b357..e486a7569752 100644 --- a/modules/libmar/tests/unit/test_create.js +++ b/modules/libmar/tests/unit/test_create.js @@ -2,7 +2,6 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { - /** * Creates MAR from the passed files, compares it to the reference MAR. * @@ -102,7 +101,7 @@ function run_test() { if (outMAR.exists()) { outMAR.remove(false); } - } + }, }; // Run all the tests diff --git a/modules/libmar/tests/unit/test_extract.js b/modules/libmar/tests/unit/test_extract.js index 9d6708a720c9..76f1e142ef89 100644 --- a/modules/libmar/tests/unit/test_extract.js +++ b/modules/libmar/tests/unit/test_extract.js @@ -2,7 +2,6 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { - /** * Extracts a MAR and makes sure each file matches the reference files. * @@ -114,7 +113,7 @@ function run_test() { return extract_and_fail("manipulated_frontend_collision.mar"); }, // Test collision detection where file B ends in file A's indexes - test_collsion_b_onto_a: function test_collsion_b_onto_a() { + test_collsion_b_onto_a: function test_collsion_b_onto_a() { return extract_and_fail("manipulated_backend_collision.mar"); }, // Test collision detection where file C shares indexes with both file A & B @@ -137,7 +136,7 @@ function run_test() { if (outDir.exists()) { outDir.remove(true); } - } + }, }; // Run all the tests diff --git a/modules/libmar/tests/unit/test_sign_verify.js b/modules/libmar/tests/unit/test_sign_verify.js index 7f094538f000..b51098983671 100644 --- a/modules/libmar/tests/unit/test_sign_verify.js +++ b/modules/libmar/tests/unit/test_sign_verify.js @@ -2,7 +2,6 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { - /** * Signs a MAR file. * @@ -568,7 +567,7 @@ function run_test() { }, // Between each test make sure the out MAR does not exist. cleanup_per_test: function _cleanup_per_test() { - } + }, }; cleanup(); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 1ec585d0bd1c..d615e4ff3920 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2375,7 +2375,6 @@ pref("network.proxy.failover_timeout", 1800); // 30 minutes pref("network.online", true); //online/offline pref("network.cookie.thirdparty.sessionOnly", false); pref("network.cookie.thirdparty.nonsecureSessionOnly", false); -pref("network.cookie.leave-secure-alone", true); pref("network.cookie.same-site.enabled", true); // Honor the SameSite cookie attribute // Cookie lifetime policy. Possible values: diff --git a/modules/libpref/test/unit/head_libPrefs.js b/modules/libpref/test/unit/head_libPrefs.js index 0cb72ded5311..e8d6b6b5c220 100644 --- a/modules/libpref/test/unit/head_libPrefs.js +++ b/modules/libpref/test/unit/head_libPrefs.js @@ -4,8 +4,7 @@ const NS_APP_USER_PROFILE_50_DIR = "ProfD"; -function do_check_throws(f, result, stack) -{ +function do_check_throws(f, result, stack) { if (!stack) stack = Components.stack.caller; @@ -18,22 +17,16 @@ function do_check_throws(f, result, stack) ok(false, "expected result " + result + ", none thrown"); } -var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); // Register current test directory as provider for the profile directory. var provider = { - getFile: function(prop, persistent) { + getFile(prop, persistent) { persistent.value = true; if (prop == NS_APP_USER_PROFILE_50_DIR) - return dirSvc.get("CurProcD", Ci.nsIFile); + return Services.dirsvc.get("CurProcD", Ci.nsIFile); throw Components.Exception("Tried to get test directory '" + prop + "'", Cr.NS_ERROR_FAILURE); }, - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIDirectoryServiceProvider) || - iid.equals(Ci.nsISupports)) { - return this; - } - throw Cr.NS_ERROR_NO_INTERFACE; - } + QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]), }; -dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); +Services.dirsvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); diff --git a/modules/libpref/test/unit/test_bug1354613.js b/modules/libpref/test/unit/test_bug1354613.js index 64ab1362bdeb..e609c6805a67 100644 --- a/modules/libpref/test/unit/test_bug1354613.js +++ b/modules/libpref/test/unit/test_bug1354613.js @@ -9,15 +9,13 @@ function run_test() { const FLOAT = 9.674; const FUDGE = 0.001; - let ps = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService); - let prefs = ps.getDefaultBranch(null); + let prefs = Services.prefs.getDefaultBranch(null); /* Test with a non-default branch */ prefs.setCharPref(FULL_PREF_NAME, FLOAT); - let pb = ps.getBranch(BRANCH); + let pb = Services.prefs.getBranch(BRANCH); let floatPref = pb.getFloatPref(PREF_NAME); - Assert.ok(FLOAT+FUDGE >= floatPref); - Assert.ok(FLOAT-FUDGE <= floatPref); + Assert.ok(FLOAT + FUDGE >= floatPref); + Assert.ok(FLOAT - FUDGE <= floatPref); } diff --git a/modules/libpref/test/unit/test_bug345529.js b/modules/libpref/test/unit/test_bug345529.js index 1b69f1581900..05fce35f5747 100644 --- a/modules/libpref/test/unit/test_bug345529.js +++ b/modules/libpref/test/unit/test_bug345529.js @@ -1,32 +1,25 @@ /* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/licenses/publicdomain/ */ + * http://creativecommons.org/licenses/publicdomain/ */ // Regression test for bug 345529 - crash removing an observer during an // nsPref:changed notification. function run_test() { const PREF_NAME = "testPref"; - var prefs = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefBranch); var observer = { - QueryInterface: function QueryInterface(aIID) { - if (aIID.equals(Ci.nsIObserver) || - aIID.equals(Ci.nsISupports)) - return this; - throw Cr.NS_NOINTERFACE; - }, + QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), observe: function observe(aSubject, aTopic, aState) { - prefs.removeObserver(PREF_NAME, observer); - } - } - prefs.addObserver(PREF_NAME, observer); + Services.prefs.removeObserver(PREF_NAME, observer); + }, + }; + Services.prefs.addObserver(PREF_NAME, observer); - prefs.setCharPref(PREF_NAME, "test0") - // This second call isn't needed on a clean profile: it makes sure + Services.prefs.setCharPref(PREF_NAME, "test0"); + // This second call isn't needed on a clean profile: it makes sure // the observer gets called even if the pref already had the value // "test0" before this test. - prefs.setCharPref(PREF_NAME, "test1") + Services.prefs.setCharPref(PREF_NAME, "test1"); Assert.ok(true); } diff --git a/modules/libpref/test/unit/test_bug506224.js b/modules/libpref/test/unit/test_bug506224.js index 870dde5f5d39..033c5acc6eac 100644 --- a/modules/libpref/test/unit/test_bug506224.js +++ b/modules/libpref/test/unit/test_bug506224.js @@ -4,10 +4,8 @@ function run_test() { const PREF_NAME = "testPref"; - var ps = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService); - var prefs = ps.getDefaultBranch(null); - var userprefs = ps.getBranch(null); + var prefs = Services.prefs.getDefaultBranch(null); + var userprefs = Services.prefs.getBranch(null); prefs.setCharPref(PREF_NAME, "test0"); prefs.lockPref(PREF_NAME); @@ -16,11 +14,11 @@ function run_test() { var file = do_get_profile(); file.append("prefs.js"); - ps.savePrefFile(file); + Services.prefs.savePrefFile(file); prefs.unlockPref(PREF_NAME); prefs.setCharPref(PREF_NAME, "test1"); - ps.readUserPrefsFromFile(file); + Services.prefs.readUserPrefsFromFile(file); Assert.equal("test1", userprefs.getCharPref(PREF_NAME)); Assert.equal(false, userprefs.prefHasUserValue(PREF_NAME)); diff --git a/modules/libpref/test/unit/test_bug577950.js b/modules/libpref/test/unit/test_bug577950.js index 0cec0cc08caf..f9106a349f14 100644 --- a/modules/libpref/test/unit/test_bug577950.js +++ b/modules/libpref/test/unit/test_bug577950.js @@ -3,26 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ function run_test() { - var ps = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService); - - var pb = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); - var observer = { - QueryInterface: function QueryInterface(aIID) { - if (aIID.equals(Ci.nsIObserver) || - aIID.equals(Ci.nsISupports)) - return this; - throw Cr.NS_NOINTERFACE; - }, + QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), observe: function observe(aSubject, aTopic, aState) { // Don't do anything. - } - } + }, + }; /* Set the same pref twice. This shouldn't leak. */ - pb.addObserver("UserPref.nonexistent.setIntPref", observer); - pb.addObserver("UserPref.nonexistent.setIntPref", observer); + Services.prefs.addObserver("UserPref.nonexistent.setIntPref", observer); + Services.prefs.addObserver("UserPref.nonexistent.setIntPref", observer); } diff --git a/modules/libpref/test/unit/test_bug790374.js b/modules/libpref/test/unit/test_bug790374.js index 9afb3620bd64..683d3ecd2260 100644 --- a/modules/libpref/test/unit/test_bug790374.js +++ b/modules/libpref/test/unit/test_bug790374.js @@ -4,10 +4,8 @@ function run_test() { const PREF_NAME = "testPref"; - var ps = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService); - var prefs = ps.getDefaultBranch(null); - var userprefs = ps.getBranch(null); + var prefs = Services.prefs.getDefaultBranch(null); + var userprefs = Services.prefs.getBranch(null); /* First, test to make sure we can parse a float from a string properly. */ prefs.setCharPref(PREF_NAME, "9.674"); @@ -15,8 +13,8 @@ function run_test() { var myFloat = 9.674; var fudge = 0.001; var floatPref = userprefs.getFloatPref(PREF_NAME); - Assert.ok(myFloat+fudge >= floatPref); - Assert.ok(myFloat-fudge <= floatPref); + Assert.ok(myFloat + fudge >= floatPref); + Assert.ok(myFloat - fudge <= floatPref); /* Now test some failure conditions. */ prefs.unlockPref(PREF_NAME); diff --git a/modules/libpref/test/unit/test_changeType.js b/modules/libpref/test/unit/test_changeType.js index 473f0698e928..49514237a820 100644 --- a/modules/libpref/test/unit/test_changeType.js +++ b/modules/libpref/test/unit/test_changeType.js @@ -10,9 +10,7 @@ const PREF_INT = 64; const PREF_STRING = 32; function run_test() { - - var ps = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService); + var ps = Services.prefs; let defaultBranch = ps.getDefaultBranch(""); let userBranch = ps.getBranch(""); @@ -39,11 +37,11 @@ function run_test() { // Prefs that have both a default and a user value -- we can't change their // type. defaultBranch.setBoolPref("TypeTest.both.bool", true); - userBranch.setBoolPref("TypeTest.both.bool", false); + userBranch.setBoolPref("TypeTest.both.bool", false); defaultBranch.setIntPref("TypeTest.both.int", 25); - userBranch.setIntPref("TypeTest.both.int", 26); + userBranch.setIntPref("TypeTest.both.int", 26); defaultBranch.setCharPref("TypeTest.both.char", "yo"); - userBranch.setCharPref("TypeTest.both.char", "ya"); + userBranch.setCharPref("TypeTest.both.char", "ya"); Assert.equal(userBranch.getBoolPref("TypeTest.both.bool"), false); Assert.equal(userBranch.getIntPref("TypeTest.both.int"), 26); @@ -52,47 +50,65 @@ function run_test() { // We only have a default value, and we try to set a default value of a // different type --> fails. do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.default.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.default.bool", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.default.bool", 5); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.default.bool", 5); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.default.int", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.default.int", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.default.int", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.default.int", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.default.char", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.default.char", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.default.char", 6); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.default.char", 6); + }, Cr.NS_ERROR_UNEXPECTED); // We only have a default value, and we try to set a user value of a // different type --> fails. do_check_throws(function() { - userBranch.setCharPref("TypeTest.default.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setCharPref("TypeTest.default.bool", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setIntPref("TypeTest.default.bool", 5); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setIntPref("TypeTest.default.bool", 5); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setCharPref("TypeTest.default.int", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setCharPref("TypeTest.default.int", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setBoolPref("TypeTest.default.int", true); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setBoolPref("TypeTest.default.int", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setBoolPref("TypeTest.default.char", true); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setBoolPref("TypeTest.default.char", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setIntPref("TypeTest.default.char", 6); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setIntPref("TypeTest.default.char", 6); + }, Cr.NS_ERROR_UNEXPECTED); // We only have a user value, and we try to set a default value of a // different type --> fails. do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.user.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.user.bool", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.user.bool", 5); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.user.bool", 5); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.user.int", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.user.int", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.user.int", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.user.int", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.user.char", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.user.char", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.user.char", 6); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.user.char", 6); + }, Cr.NS_ERROR_UNEXPECTED); // We only have a user value, and we try to set a user value of a // different type --> SUCCEEDS. @@ -112,30 +128,42 @@ function run_test() { // We have both a default value and user value, and we try to set a default // value of a different type --> fails. do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.both.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.both.bool", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.both.bool", 5); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.both.bool", 5); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setCharPref("TypeTest.both.int", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setCharPref("TypeTest.both.int", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.both.int", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.both.int", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setBoolPref("TypeTest.both.char", true); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setBoolPref("TypeTest.both.char", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - defaultBranch.setIntPref("TypeTest.both.char", 6); }, Cr.NS_ERROR_UNEXPECTED); + defaultBranch.setIntPref("TypeTest.both.char", 6); + }, Cr.NS_ERROR_UNEXPECTED); // We have both a default value and user value, and we try to set a user // value of a different type --> fails. do_check_throws(function() { - userBranch.setCharPref("TypeTest.both.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setCharPref("TypeTest.both.bool", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setIntPref("TypeTest.both.bool", 5); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setIntPref("TypeTest.both.bool", 5); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setCharPref("TypeTest.both.int", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setCharPref("TypeTest.both.int", "boo"); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setBoolPref("TypeTest.both.int", true); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setBoolPref("TypeTest.both.int", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setBoolPref("TypeTest.both.char", true); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setBoolPref("TypeTest.both.char", true); + }, Cr.NS_ERROR_UNEXPECTED); do_check_throws(function() { - userBranch.setIntPref("TypeTest.both.char", 6); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setIntPref("TypeTest.both.char", 6); + }, Cr.NS_ERROR_UNEXPECTED); } diff --git a/modules/libpref/test/unit/test_defaultValues.js b/modules/libpref/test/unit/test_defaultValues.js index 8384f7accc60..4b0a24978958 100644 --- a/modules/libpref/test/unit/test_defaultValues.js +++ b/modules/libpref/test/unit/test_defaultValues.js @@ -5,10 +5,7 @@ /* Tests for providing a default value to get{Bool,Char,Float,Int}Pref */ function run_test() { - var ps = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService) - .QueryInterface(Ci.nsIPrefBranch); - + const ps = Services.prefs; let prefName = "test.default.values.bool"; do_check_throws(function() { ps.getBoolPref(prefName); }, Cr.NS_ERROR_UNEXPECTED); diff --git a/modules/libpref/test/unit/test_dirtyPrefs.js b/modules/libpref/test/unit/test_dirtyPrefs.js index e7afb855c96c..3823843a9fc1 100644 --- a/modules/libpref/test/unit/test_dirtyPrefs.js +++ b/modules/libpref/test/unit/test_dirtyPrefs.js @@ -10,9 +10,7 @@ const PREF_INT = 64; const PREF_STRING = 32; function run_test() { - - var ps = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService); + const ps = Services.prefs; let defaultBranch = ps.getDefaultBranch(""); let userBranch = ps.getBranch(""); @@ -20,7 +18,7 @@ function run_test() { let prefFile = do_get_profile(); prefFile.append("prefs.js"); - //**************************************************************************// + //* *************************************************************************// // prefs are not dirty after a write ps.savePrefFile(null); Assert.ok(!ps.dirty); @@ -58,7 +56,8 @@ function run_test() { Assert.ok(!ps.dirty); // Fail to change type of a pref with default value -> not dirty do_check_throws(function() { - userBranch.setCharPref("DirtyTest.existing.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED); + userBranch.setCharPref("DirtyTest.existing.bool", "boo"); +}, Cr.NS_ERROR_UNEXPECTED); Assert.ok(!ps.dirty); // Set user value same as default, not dirty diff --git a/modules/libpref/test/unit/test_libPrefs.js b/modules/libpref/test/unit/test_libPrefs.js index 375f11944c90..1f2cf685a300 100644 --- a/modules/libpref/test/unit/test_libPrefs.js +++ b/modules/libpref/test/unit/test_libPrefs.js @@ -9,153 +9,163 @@ const PREF_STRING = 32; const MAX_PREF_LENGTH = 1 * 1024 * 1024; -function makeList(a) -{ +function makeList(a) { var o = {}; - for(var i=0; i { let complete = false; let listener = { - observe: function(event) { + observe(event) { let message = event.message; if (!(message.startsWith("Warning: attempting to write") && message.includes(pref))) { @@ -31,9 +25,9 @@ function checkWarning(pref, buffer) { } complete = true; info("Warning while setting " + pref); - cs.unregisterListener(listener); + Services.console.unregisterListener(listener); resolve(true); - } + }, }; do_timeout(1000, function() { if (complete) { @@ -41,18 +35,14 @@ function checkWarning(pref, buffer) { } complete = true; info("No warning while setting " + pref); - cs.unregisterListener(listener); + Services.console.unregisterListener(listener); resolve(false); }); - cs.registerListener(listener); - ps.setCharPref(pref, buffer); + Services.console.registerListener(listener); + Services.prefs.setCharPref(pref, buffer); }); } -function run_test() { - run_next_test(); -} - add_task(async function() { // Simple change, shouldn't cause a warning info("Checking that a simple change doesn't cause a warning"); diff --git a/modules/libpref/test/unit_ipc/test_existing_prefs.js b/modules/libpref/test/unit_ipc/test_existing_prefs.js index 3efca18d9461..3955dbb07fae 100644 --- a/modules/libpref/test/unit_ipc/test_existing_prefs.js +++ b/modules/libpref/test/unit_ipc/test_existing_prefs.js @@ -1,18 +1,19 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + function isParentProcess() { let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return (!appInfo || Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); } function run_test() { - if (isParentProcess() == false) { - + if (!isParentProcess()) { do_load_child_test_harness(); - - var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + + var pb = Services.prefs; pb.setBoolPref("Test.IPC.bool.new", true); pb.setIntPref("Test.IPC.int.new", 23); pb.setCharPref("Test.IPC.char.new", "hey"); run_test_in_child("test_observed_prefs.js"); } -} \ No newline at end of file +} diff --git a/modules/libpref/test/unit_ipc/test_initial_prefs.js b/modules/libpref/test/unit_ipc/test_initial_prefs.js index 21511ab9be35..cf84413dad67 100644 --- a/modules/libpref/test/unit_ipc/test_initial_prefs.js +++ b/modules/libpref/test/unit_ipc/test_initial_prefs.js @@ -1,15 +1,16 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + function isParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); } function run_test() { - if (isParentProcess() == false) { - var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - pb.setBoolPref("Test.IPC.bool", true); - pb.setIntPref("Test.IPC.int", 23); - pb.setCharPref("Test.IPC.char", "hey"); + if (!isParentProcess()) { + const pb = Services.prefs; + pb.setBoolPref("Test.IPC.bool", true); + pb.setIntPref("Test.IPC.int", 23); + pb.setCharPref("Test.IPC.char", "hey"); - run_test_in_child("test_existing_prefs.js"); + run_test_in_child("test_existing_prefs.js"); } } diff --git a/modules/libpref/test/unit_ipc/test_large_pref.js b/modules/libpref/test/unit_ipc/test_large_pref.js index ac3acffac788..d8d5d28ead7e 100644 --- a/modules/libpref/test/unit_ipc/test_large_pref.js +++ b/modules/libpref/test/unit_ipc/test_large_pref.js @@ -5,21 +5,22 @@ // Large preferences should not be set in the child process. // Non-string preferences are not tested here, because their behavior // should not be affected by this filtering. +// +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); function isParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); } function makeBuffer(length) { - let string = "x"; - while (string.length < length) { - string = string + string; - } - if (string.length > length) { - string = string.substring(length - string.length); - } - return string; + let string = "x"; + while (string.length < length) { + string = string + string; + } + if (string.length > length) { + string = string.substring(length - string.length); + } + return string; } // from prefapi.h @@ -46,9 +47,8 @@ function expectedPrefValue(def, user) { } function run_test() { - let pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - let ps = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); - let defaultBranch = ps.getDefaultBranch(""); + const pb = Services.prefs; + let defaultBranch = pb.getDefaultBranch(""); let isParent = isParentProcess(); if (isParent) { @@ -92,11 +92,11 @@ function run_test() { try { let val = pb.getCharPref(pref_name); prefExists = val.length > 128; - } catch(e) { + } catch (e) { prefExists = false; } ok(!prefExists, - "Pref " + pref_name + " should not be set in the child"); + "Pref " + pref_name + " should not be set in the child"); } } } diff --git a/modules/libpref/test/unit_ipc/test_locked_prefs.js b/modules/libpref/test/unit_ipc/test_locked_prefs.js index 11aa046cd77c..359c236449c0 100644 --- a/modules/libpref/test/unit_ipc/test_locked_prefs.js +++ b/modules/libpref/test/unit_ipc/test_locked_prefs.js @@ -4,13 +4,14 @@ // Locked status should be communicated to children. +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + function isParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); } function run_test() { - let pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + const pb = Services.prefs; let bprefname = "Test.IPC.locked.bool"; let iprefname = "Test.IPC.locked.int"; diff --git a/modules/libpref/test/unit_ipc/test_observed_prefs.js b/modules/libpref/test/unit_ipc/test_observed_prefs.js index 406696997d70..acd4340e023f 100644 --- a/modules/libpref/test/unit_ipc/test_observed_prefs.js +++ b/modules/libpref/test/unit_ipc/test_observed_prefs.js @@ -1,13 +1,14 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + function isParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); } function run_test() { - if (isParentProcess() == false) { - var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - Assert.equal(pb.getBoolPref("Test.IPC.bool.new"), true); - Assert.equal(pb.getIntPref("Test.IPC.int.new"), 23); - Assert.equal(pb.getCharPref("Test.IPC.char.new"), "hey"); + if (!isParentProcess()) { + const pb = Services.prefs; + Assert.equal(pb.getBoolPref("Test.IPC.bool.new"), true); + Assert.equal(pb.getIntPref("Test.IPC.int.new"), 23); + Assert.equal(pb.getCharPref("Test.IPC.char.new"), "hey"); } } diff --git a/modules/libpref/test/unit_ipc/test_sharedMap.js b/modules/libpref/test/unit_ipc/test_sharedMap.js index c09b1b071d85..5c0e44beed09 100644 --- a/modules/libpref/test/unit_ipc/test_sharedMap.js +++ b/modules/libpref/test/unit_ipc/test_sharedMap.js @@ -152,7 +152,6 @@ const PREFS = [ for (let {type, values} of PREFS) { let set = `set${type}Pref`; - let get = `get${type}Pref`; function prefTest(opts) { function check(pref, proc, val, {expectedVal, defaultVal = undefined, expectedDefault = defaultVal, expectedFlags = {}}) { @@ -179,14 +178,14 @@ for (let {type, values} of PREFS) { return { beforeContent(PREF) { - updatePref(PREF, opts.initial) + updatePref(PREF, opts.initial); check(PREF, "parent", getPref(PREF), opts.initial); }, contentStartup(PREF, contentVal) { check(PREF, "content", contentVal, opts.initial); check(PREF, "parent", getPref(PREF), opts.initial); - updatePref(PREF, opts.change1) + updatePref(PREF, opts.change1); check(PREF, "parent", getPref(PREF), opts.change1); }, contentUpdate1(PREF, contentVal) { @@ -194,7 +193,7 @@ for (let {type, values} of PREFS) { check(PREF, "parent", getPref(PREF), opts.change1); if (opts.change2) { - updatePref(PREF, opts.change2) + updatePref(PREF, opts.change2); check(PREF, "parent", getPref(PREF), opts.change2); } }, diff --git a/modules/libpref/test/unit_ipc/test_sharedMap_var_caches.js b/modules/libpref/test/unit_ipc/test_sharedMap_var_caches.js index e9e229ff9068..42dac022c41c 100644 --- a/modules/libpref/test/unit_ipc/test_sharedMap_var_caches.js +++ b/modules/libpref/test/unit_ipc/test_sharedMap_var_caches.js @@ -22,7 +22,7 @@ const PREF1_NAME = "dom.webcomponents.shadowdom.report_usage"; const PREF1_VALUE = false; -const PREF2_NAME = "dom.mutation-events.cssom.disabled" +const PREF2_NAME = "dom.mutation-events.cssom.disabled"; const PREF2_VALUE = true; const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); @@ -30,8 +30,6 @@ const {ExtensionTestUtils} = ChromeUtils.import("resource://testing-common/Exten ExtensionTestUtils.init(this); -let contentPage; - const {prefs} = Services; const defaultPrefs = prefs.getDefaultBranch(""); @@ -52,14 +50,15 @@ add_task(async function test_sharedMap_var_caches() { let contentPage = await ExtensionTestUtils.loadContentPage("about:blank", {remote: true}); registerCleanupFunction(() => contentPage.close()); + /* eslint-disable no-shadow */ let values = await contentPage.spawn([PREF1_NAME, PREF2_NAME], (prefs) => { const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); return prefs.map(pref => Services.prefs.getBoolPref(pref)); - }) + }); + /* eslint-enable no-shadow */ equal(values[0], !PREF1_VALUE, `Expected content value for ${PREF1_NAME}`); equal(values[1], !PREF2_VALUE, `Expected content value for ${PREF2_NAME}`); }); - diff --git a/modules/libpref/test/unit_ipc/test_update_prefs.js b/modules/libpref/test/unit_ipc/test_update_prefs.js index 6f512647189e..30739aa026b6 100644 --- a/modules/libpref/test/unit_ipc/test_update_prefs.js +++ b/modules/libpref/test/unit_ipc/test_update_prefs.js @@ -1,14 +1,14 @@ +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + function isParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); + return Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; } function run_test() { if (isParentProcess()) { - do_load_child_test_harness(); - var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + var pb = Services.prefs; // these prefs are set after the child has been created. pb.setBoolPref("Test.IPC.bool.new", true); @@ -20,11 +20,11 @@ function run_test() { } function testPrefClear() { - var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + var pb = Services.prefs; pb.clearUserPref("Test.IPC.bool.new"); sendCommand( -'var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);\n'+ +'var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);\n' + 'pb.prefHasUserValue("Test.IPC.bool.new");\n', checkWasCleared); } diff --git a/modules/libpref/test/unit_ipc/test_user_default_prefs.js b/modules/libpref/test/unit_ipc/test_user_default_prefs.js index 005895d8e47f..a866c79eb342 100644 --- a/modules/libpref/test/unit_ipc/test_user_default_prefs.js +++ b/modules/libpref/test/unit_ipc/test_user_default_prefs.js @@ -1,67 +1,68 @@ -var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); +const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const pb = Services.prefs; // This pref is chosen somewhat arbitrarily --- we just need one // that's guaranteed to have a default value. -const kPrefName = 'intl.accept_languages'; // of type char, which we +const kPrefName = "intl.accept_languages"; // of type char, which we // assume below var initialValue = null; function check_child_pref_info_eq(continuation) { - sendCommand( - 'var pb = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);\n'+ - // Returns concatenation "[value],[isUser]" - 'pb.getCharPref("'+ kPrefName +'")+ "," +'+ - 'pb.prefHasUserValue("'+ kPrefName +'");', - function (info) { - let [ value, isUser ] = info.split(','); - Assert.equal(pb.getCharPref(kPrefName), value); - Assert.equal(pb.prefHasUserValue(kPrefName), isUser == "true"); - continuation(); - }); + sendCommand( + 'var pb = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);\n' + + // Returns concatenation "[value],[isUser]" + 'pb.getCharPref("' + kPrefName + '")+ "," +' + + 'pb.prefHasUserValue("' + kPrefName + '");', + function(info) { + let [ value, isUser ] = info.split(","); + Assert.equal(pb.getCharPref(kPrefName), value); + Assert.equal(pb.prefHasUserValue(kPrefName), isUser == "true"); + continuation(); + }); } function run_test() { - // We finish in clean_up() - do_test_pending(); + // We finish in clean_up() + do_test_pending(); - initialValue = pb.getCharPref(kPrefName); + initialValue = pb.getCharPref(kPrefName); - test_user_setting(); + test_user_setting(); } function test_user_setting() { - // We rely on setting this before the content process starts up. - // When it starts up, it should recognize this as a user pref, not - // a default pref. - pb.setCharPref(kPrefName, 'i-imaginarylanguage'); - // NB: processing of the value-change notification in the child - // process triggered by the above set happens-before the remaining - // code here - check_child_pref_info_eq(function () { - Assert.equal(pb.prefHasUserValue(kPrefName), true); + // We rely on setting this before the content process starts up. + // When it starts up, it should recognize this as a user pref, not + // a default pref. + pb.setCharPref(kPrefName, "i-imaginarylanguage"); + // NB: processing of the value-change notification in the child + // process triggered by the above set happens-before the remaining + // code here + check_child_pref_info_eq(function() { + Assert.equal(pb.prefHasUserValue(kPrefName), true); - test_cleared_is_default(); - }); + test_cleared_is_default(); + }); } function test_cleared_is_default() { - pb.clearUserPref(kPrefName); - // NB: processing of the value-change notification in the child - // process triggered by the above set happens-before the remaining - // code here - check_child_pref_info_eq(function () { - Assert.equal(pb.prefHasUserValue(kPrefName), false); + pb.clearUserPref(kPrefName); + // NB: processing of the value-change notification in the child + // process triggered by the above set happens-before the remaining + // code here + check_child_pref_info_eq(function() { + Assert.equal(pb.prefHasUserValue(kPrefName), false); - clean_up(); - }); + clean_up(); + }); } function clean_up() { - pb.setCharPref(kPrefName, initialValue); - // NB: processing of the value-change notification in the child - // process triggered by the above set happens-before the remaining - // code here - check_child_pref_info_eq(function () { - do_test_finished(); - }); + pb.setCharPref(kPrefName, initialValue); + // NB: processing of the value-change notification in the child + // process triggered by the above set happens-before the remaining + // code here + check_child_pref_info_eq(function() { + do_test_finished(); + }); } diff --git a/netwerk/cookie/CookieServiceChild.cpp b/netwerk/cookie/CookieServiceChild.cpp index 78b90522348d..8216594af8f6 100644 --- a/netwerk/cookie/CookieServiceChild.cpp +++ b/netwerk/cookie/CookieServiceChild.cpp @@ -40,8 +40,6 @@ static const char kPrefThirdPartySession[] = "network.cookie.thirdparty.sessionOnly"; static const char kPrefThirdPartyNonsecureSession[] = "network.cookie.thirdparty.nonsecureSessionOnly"; -static const char kCookieLeaveSecurityAlone[] = - "network.cookie.leave-secure-alone"; static const char kCookieMoveIntervalSecs[] = "network.cookie.move.interval_sec"; @@ -64,7 +62,6 @@ CookieServiceChild::CookieServiceChild() : mCookieBehavior(nsICookieService::BEHAVIOR_ACCEPT), mThirdPartySession(false), mThirdPartyNonsecureSession(false), - mLeaveSecureAlone(true), mIPCOpen(false) { NS_ASSERTION(IsNeckoChild(), "not a child process"); @@ -94,7 +91,6 @@ CookieServiceChild::CookieServiceChild() prefBranch->AddObserver(kPrefCookieBehavior, this, true); prefBranch->AddObserver(kPrefThirdPartySession, this, true); prefBranch->AddObserver(kPrefThirdPartyNonsecureSession, this, true); - prefBranch->AddObserver(kCookieLeaveSecurityAlone, this, true); prefBranch->AddObserver(kCookieMoveIntervalSecs, this, true); PrefChanged(prefBranch); } @@ -271,10 +267,6 @@ void CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch) { aPrefBranch->GetBoolPref(kPrefThirdPartyNonsecureSession, &boolval))) mThirdPartyNonsecureSession = boolval; - if (NS_SUCCEEDED( - aPrefBranch->GetBoolPref(kCookieLeaveSecurityAlone, &boolval))) - mLeaveSecureAlone = !!boolval; - if (!mThirdPartyUtil && RequireThirdPartyCheck()) { mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); NS_ASSERTION(mThirdPartyUtil, "require ThirdPartyUtil service"); @@ -607,8 +599,8 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI, bool canSetCookie = false; moreCookies = nsCookieService::CanSetCookie( aHostURI, key, cookieAttributes, requireHostMatch, cookieStatus, - cookieString, serverTime, aFromHttp, aChannel, mLeaveSecureAlone, - canSetCookie, mThirdPartyUtil); + cookieString, serverTime, aFromHttp, aChannel, canSetCookie, + mThirdPartyUtil); // We need to see if the cookie we're setting would overwrite an httponly // one. This would not affect anything we send over the net (those come from diff --git a/netwerk/cookie/CookieServiceChild.h b/netwerk/cookie/CookieServiceChild.h index 98a782919f54..c15e27cc43d2 100644 --- a/netwerk/cookie/CookieServiceChild.h +++ b/netwerk/cookie/CookieServiceChild.h @@ -110,7 +110,6 @@ class CookieServiceChild : public PCookieServiceChild, uint8_t mCookieBehavior; bool mThirdPartySession; bool mThirdPartyNonsecureSession; - bool mLeaveSecureAlone; bool mIPCOpen; }; diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 12e007db3f54..bec76f1fbba2 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -134,19 +134,6 @@ static const char kPrefThirdPartySession[] = "network.cookie.thirdparty.sessionOnly"; static const char kPrefThirdPartyNonsecureSession[] = "network.cookie.thirdparty.nonsecureSessionOnly"; -static const char kCookieLeaveSecurityAlone[] = - "network.cookie.leave-secure-alone"; - -// For telemetry COOKIE_LEAVE_SECURE_ALONE -#define BLOCKED_SECURE_SET_FROM_HTTP 0 -#define BLOCKED_DOWNGRADE_SECURE_INEXACT 1 -#define DOWNGRADE_SECURE_FROM_SECURE_INEXACT 2 -#define EVICTED_NEWER_INSECURE 3 -#define EVICTED_OLDEST_COOKIE 4 -#define EVICTED_PREFERRED_COOKIE 5 -#define EVICTING_SECURE_BLOCKED 6 -#define BLOCKED_DOWNGRADE_SECURE_EXACT 7 -#define DOWNGRADE_SECURE_FROM_SECURE_EXACT 8 static void bindCookieParameters(mozIStorageBindingParamsArray *aParamsArray, const nsCookieKey &aKey, @@ -601,7 +588,6 @@ nsCookieService::nsCookieService() mCookieBehavior(nsICookieService::BEHAVIOR_ACCEPT), mThirdPartySession(false), mThirdPartyNonsecureSession(false), - mLeaveSecureAlone(true), mMaxNumberOfCookies(kMaxNumberOfCookies), mMaxCookiesPerHost(kMaxCookiesPerHost), mCookieQuotaPerHost(kCookieQuotaPerHost), @@ -631,7 +617,6 @@ nsresult nsCookieService::Init() { prefBranch->AddObserver(kPrefCookiePurgeAge, this, true); prefBranch->AddObserver(kPrefThirdPartySession, this, true); prefBranch->AddObserver(kPrefThirdPartyNonsecureSession, this, true); - prefBranch->AddObserver(kCookieLeaveSecurityAlone, this, true); PrefChanged(prefBranch); } @@ -2403,10 +2388,6 @@ void nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch) { if (NS_SUCCEEDED( aPrefBranch->GetBoolPref(kPrefThirdPartyNonsecureSession, &boolval))) mThirdPartyNonsecureSession = boolval; - - if (NS_SUCCEEDED( - aPrefBranch->GetBoolPref(kCookieLeaveSecurityAlone, &boolval))) - mLeaveSecureAlone = boolval; } /****************************************************************************** @@ -3239,8 +3220,7 @@ bool nsCookieService::CanSetCookie(nsIURI *aHostURI, const nsCookieKey &aKey, bool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, int64_t aServerTime, bool aFromHttp, - nsIChannel *aChannel, bool aLeaveSecureAlone, - bool &aSetCookie, + nsIChannel *aChannel, bool &aSetCookie, mozIThirdPartyUtil *aThirdPartyUtil) { NS_ASSERTION(aHostURI, "null host!"); @@ -3373,11 +3353,9 @@ bool nsCookieService::CanSetCookie(nsIURI *aHostURI, const nsCookieKey &aKey, // If the new cookie is non-https and wants to set secure flag, // browser have to ignore this new cookie. // (draft-ietf-httpbis-cookie-alone section 3.1) - if (aLeaveSecureAlone && aCookieAttributes.isSecure && !isSecure) { + if (aCookieAttributes.isSecure && !isSecure) { COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "non-https cookie can't set secure flag"); - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - BLOCKED_SECURE_SET_FROM_HTTP); return newCookie; } @@ -3427,7 +3405,7 @@ bool nsCookieService::SetCookieInternal(nsIURI *aHostURI, bool newCookie = CanSetCookie(aHostURI, aKey, cookieAttributes, aRequireHostMatch, aStatus, aCookieHeader, aServerTime, aFromHttp, aChannel, - mLeaveSecureAlone, canSetCookie, mThirdPartyUtil); + canSetCookie, mThirdPartyUtil); if (!canSetCookie) { return newCookie; @@ -3498,42 +3476,22 @@ void nsCookieService::AddInternal(const nsCookieKey &aKey, nsCookie *aCookie, isSecure = false; } bool oldCookieIsSession = false; - if (mLeaveSecureAlone) { - // Step1, call FindSecureCookie(). FindSecureCookie() would - // find the existing cookie with the security flag and has - // the same name, host and path of the new cookie, if there is any. - // Step2, Confirm new cookie's security setting. If any targeted - // cookie had been found in Step1, then confirm whether the - // new cookie could modify it. If the new created cookie’s - // "secure-only-flag" is not set, and the "scheme" component - // of the "request-uri" does not denote a "secure" protocol, - // then ignore the new cookie. - // (draft-ietf-httpbis-cookie-alone section 3.2) - if (!aCookie->IsSecure() && - (foundSecureExact || FindSecureCookie(aKey, aCookie))) { - if (!isSecure) { - COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, - "cookie can't save because older cookie is secure " - "cookie but newer cookie is non-secure cookie"); - if (foundSecureExact) { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - BLOCKED_DOWNGRADE_SECURE_EXACT); - } else { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - BLOCKED_DOWNGRADE_SECURE_INEXACT); - } - return; - } - // A secure site is allowed to downgrade a secure cookie - // but we want to measure anyway. - if (foundSecureExact) { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - DOWNGRADE_SECURE_FROM_SECURE_EXACT); - } else { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - DOWNGRADE_SECURE_FROM_SECURE_INEXACT); - } - } + // Step1, call FindSecureCookie(). FindSecureCookie() would + // find the existing cookie with the security flag and has + // the same name, host and path of the new cookie, if there is any. + // Step2, Confirm new cookie's security setting. If any targeted + // cookie had been found in Step1, then confirm whether the + // new cookie could modify it. If the new created cookie’s + // "secure-only-flag" is not set, and the "scheme" component + // of the "request-uri" does not denote a "secure" protocol, + // then ignore the new cookie. + // (draft-ietf-httpbis-cookie-alone section 3.2) + if (!aCookie->IsSecure() && + (foundSecureExact || FindSecureCookie(aKey, aCookie)) && !isSecure) { + COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, + "cookie can't save because older cookie is secure " + "cookie but newer cookie is non-secure cookie"); + return; } RefPtr oldCookie; @@ -3624,19 +3582,13 @@ void nsCookieService::AddInternal(const nsCookieKey &aKey, nsCookie *aCookie, nsTArray removedIterList; // Prioritize evicting insecure cookies. // (draft-ietf-httpbis-cookie-alone section 3.3) - mozilla::Maybe optionalSecurity = - mLeaveSecureAlone ? Some(false) : Nothing(); uint32_t limit = mMaxCookiesPerHost - mCookieQuotaPerHost; - FindStaleCookies(entry, currentTime, optionalSecurity, removedIterList, - limit); + FindStaleCookies(entry, currentTime, false, removedIterList, limit); if (removedIterList.Length() == 0) { if (aCookie->IsSecure()) { // It's valid to evict a secure cookie for another secure cookie. - FindStaleCookies(entry, currentTime, Some(true), removedIterList, - limit); + FindStaleCookies(entry, currentTime, true, removedIterList, limit); } else { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - EVICTING_SECURE_BLOCKED); COOKIE_LOGEVICTED(aCookie, "Too many cookies for this domain and the new " "cookie is not a secure cookie"); @@ -3651,10 +3603,6 @@ void nsCookieService::AddInternal(const nsCookieKey &aKey, nsCookie *aCookie, for (auto it = removedIterList.rbegin(); it != removedIterList.rend(); it++) { RefPtr evictedCookie = (*it).Cookie(); - if (mLeaveSecureAlone && evictedCookie->Expiry() <= currentTime) { - TelemetryForEvictingStaleCookie(evictedCookie, - evictedCookie->LastAccessed()); - } COOKIE_LOGEVICTED(evictedCookie, "Too many cookies for this domain"); RemoveCookieFromList(*it); CreateOrUpdatePurgeList(getter_AddRefs(purgedList), evictedCookie); @@ -4571,8 +4519,7 @@ class CookieIterComparator { // Given the output iter array and the count limit, find cookies // sort by expiry and lastAccessed time. void nsCookieService::FindStaleCookies(nsCookieEntry *aEntry, - int64_t aCurrentTime, - const mozilla::Maybe &aIsSecure, + int64_t aCurrentTime, bool aIsSecure, nsTArray &aOutput, uint32_t aLimit) { MOZ_ASSERT(aLimit); @@ -4591,7 +4538,7 @@ void nsCookieService::FindStaleCookies(nsCookieEntry *aEntry, continue; } - if (aIsSecure.isSome() && !aIsSecure.value()) { + if (!aIsSecure) { // We want to look for the non-secure cookie first time through, // then find the secure cookie the second time this function is called. if (cookie->IsSecure()) { @@ -4609,23 +4556,6 @@ void nsCookieService::FindStaleCookies(nsCookieEntry *aEntry, } } -void nsCookieService::TelemetryForEvictingStaleCookie( - nsCookie *aEvicted, int64_t oldestCookieTime) { - // We need to record the evicting cookie to telemetry. - if (!aEvicted->IsSecure()) { - if (aEvicted->LastAccessed() > oldestCookieTime) { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - EVICTED_NEWER_INSECURE); - } else { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - EVICTED_OLDEST_COOKIE); - } - } else { - Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE, - EVICTED_PREFERRED_COOKIE); - } -} - // count the number of cookies stored by a particular host. this is provided by // the nsICookieManager interface. NS_IMETHODIMP diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 44a5a2dc1886..b48cf51fd2a0 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -255,8 +255,7 @@ class nsCookieService final : public nsICookieService, bool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, int64_t aServerTime, bool aFromHttp, - nsIChannel *aChannel, bool aLeaveSercureAlone, - bool &aSetCookie, + nsIChannel *aChannel, bool &aSetCookie, mozIThirdPartyUtil *aThirdPartyUtil); static CookieStatus CheckPrefs( nsICookiePermission *aPermissionServices, uint8_t aCookieBehavior, @@ -353,10 +352,8 @@ class nsCookieService final : public nsICookieService, nsListIter &aIter); bool FindSecureCookie(const nsCookieKey &aKey, nsCookie *aCookie); void FindStaleCookies(nsCookieEntry *aEntry, int64_t aCurrentTime, - const mozilla::Maybe &aIsSecure, - nsTArray &aOutput, uint32_t aLimit); - void TelemetryForEvictingStaleCookie(nsCookie *aEvicted, - int64_t oldestCookieTime); + bool aIsSecure, nsTArray &aOutput, + uint32_t aLimit); void NotifyAccepted(nsIChannel *aChannel); void NotifyRejected(nsIURI *aHostURI, nsIChannel *aChannel, uint32_t aRejectedReason, CookieOperation aOperation); @@ -406,7 +403,6 @@ class nsCookieService final : public nsICookieService, // LIMITFOREIGN} bool mThirdPartySession; bool mThirdPartyNonsecureSession; - bool mLeaveSecureAlone; uint16_t mMaxNumberOfCookies; uint16_t mMaxCookiesPerHost; uint16_t mCookieQuotaPerHost; diff --git a/netwerk/test/TestCookie.cpp b/netwerk/test/TestCookie.cpp index c9258326d547..44855bc1b62b 100644 --- a/netwerk/test/TestCookie.cpp +++ b/netwerk/test/TestCookie.cpp @@ -32,8 +32,6 @@ static NS_DEFINE_CID(kPrefServiceCID, NS_PREFSERVICE_CID); static const char kCookiesPermissions[] = "network.cookie.cookieBehavior"; static const char kPrefCookieQuotaPerHost[] = "network.cookie.quotaPerHost"; static const char kCookiesMaxPerHost[] = "network.cookie.maxPerHost"; -static const char kCookieLeaveSecurityAlone[] = - "network.cookie.leave-secure-alone"; #define OFFSET_ONE_WEEK int64_t(604800) * PR_USEC_PER_SEC #define OFFSET_ONE_DAY int64_t(86400) * PR_USEC_PER_SEC @@ -176,7 +174,6 @@ void InitPrefs(nsIPrefBranch *aPrefBranch) { // we use the most restrictive set of prefs we can; // however, we don't test third party blocking here. aPrefBranch->SetIntPref(kCookiesPermissions, 0); // accept all - aPrefBranch->SetBoolPref(kCookieLeaveSecurityAlone, true); // Set quotaPerHost to maxPerHost - 1, so there is only one cookie // will be evicted everytime. aPrefBranch->SetIntPref(kPrefCookieQuotaPerHost, 49); @@ -980,8 +977,6 @@ TEST(TestCookie, TestCookieMain) { GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, cookie); EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, expected.get())); - // *** eviction and creation ordering tests after enable - // network.cookie.leave-secure-alone reset cookie cookieMgr->RemoveAll(); for (int32_t i = 0; i < 60; ++i) { diff --git a/python/mozbuild/mozbuild/preprocessor.py b/python/mozbuild/mozbuild/preprocessor.py index 6780b8b72142..200651712ab5 100644 --- a/python/mozbuild/mozbuild/preprocessor.py +++ b/python/mozbuild/mozbuild/preprocessor.py @@ -45,6 +45,15 @@ __all__ = [ ] +def path_starts_with(path, prefix): + if os.altsep: + prefix = prefix.replace(os.altsep, os.sep) + path = path.replace(os.altsep, os.sep) + prefix = [os.path.normcase(p) for p in prefix.split(os.sep)] + path = [os.path.normcase(p) for p in path.split(os.sep)] + return path[:len(prefix)] == prefix + + class Expression: def __init__(self, expression_string): """ @@ -280,6 +289,15 @@ class Preprocessor: 'LINE': 0, 'DIRECTORY': os.path.abspath('.')}.iteritems(): self.context[k] = v + try: + # Can import globally because of bootstrapping issues. + from buildconfig import topsrcdir, topobjdir + except ImportError: + # Allow this script to still work independently of a configured objdir. + topsrcdir = topobjdir = None + self.topsrcdir = topsrcdir + self.topobjdir = topobjdir + self.curdir = '.' self.actionLevel = 0 self.disableLevel = 0 # ifStates can be @@ -747,7 +765,7 @@ class Preprocessor: if filters: args = self.applyFilters(args) if not os.path.isabs(args): - args = os.path.join(self.context['DIRECTORY'], args) + args = os.path.join(self.curdir, args) args = open(args, 'rU') except Preprocessor.Error: raise @@ -757,15 +775,22 @@ class Preprocessor: oldFile = self.context['FILE'] oldLine = self.context['LINE'] oldDir = self.context['DIRECTORY'] + oldCurdir = self.curdir self.noteLineInfo() if args.isatty(): # we're stdin, use '-' and '' for file and dir self.context['FILE'] = '-' self.context['DIRECTORY'] = '' + self.curdir = '.' else: abspath = os.path.abspath(args.name) + self.curdir = os.path.dirname(abspath) self.includes.add(abspath) + if self.topobjdir and path_starts_with(abspath, self.topobjdir): + abspath = '$OBJDIR' + abspath[len(self.topobjdir):] + elif self.topsrcdir and path_starts_with(abspath, self.topsrcdir): + abspath = '$SRCDIR' + abspath[len(self.topsrcdir):] self.context['FILE'] = abspath self.context['DIRECTORY'] = os.path.dirname(abspath) self.context['LINE'] = 0 @@ -780,6 +805,7 @@ class Preprocessor: self.checkLineNumbers = oldCheckLineNumbers self.context['LINE'] = oldLine self.context['DIRECTORY'] = oldDir + self.curdir = oldCurdir def do_includesubst(self, args): args = self.filter_substitution(args) self.do_include(args) diff --git a/python/mozbuild/mozbuild/test/backend/test_build.py b/python/mozbuild/mozbuild/test/backend/test_build.py index 4b39f52e601e..ada6d6e75b7b 100644 --- a/python/mozbuild/mozbuild/test/backend/test_build.py +++ b/python/mozbuild/mozbuild/test/backend/test_build.py @@ -148,8 +148,8 @@ class TestBuild(unittest.TestCase): def validate(self, config): self.maxDiff = None - test_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'data', 'build') + os.sep + test_path = os.sep.join(('$SRCDIR', 'python', 'mozbuild', 'mozbuild', + 'test', 'backend', 'data', 'build')) + os.sep # We want unicode instances out of the files, because having plain str # makes assertEqual diff output in case of error extra verbose because diff --git a/python/mozbuild/mozbuild/test/test_preprocessor.py b/python/mozbuild/mozbuild/test/test_preprocessor.py index a4e72ac54459..e17a24f66a2e 100644 --- a/python/mozbuild/mozbuild/test/test_preprocessor.py +++ b/python/mozbuild/mozbuild/test/test_preprocessor.py @@ -567,53 +567,67 @@ class TestPreprocessor(unittest.TestCase): def test_include_line(self): files = { - 'test.js': '\n'.join([ + 'srcdir/test.js': '\n'.join([ '#define foo foobarbaz', '#include @inc@', '@bar@', '', ]), - 'bar.js': '\n'.join([ + 'srcdir/bar.js': '\n'.join([ '#define bar barfoobaz', '@foo@', '', ]), - 'foo.js': '\n'.join([ + 'srcdir/foo.js': '\n'.join([ 'bazfoobar', '#include bar.js', 'bazbarfoo', '', ]), - 'baz.js': 'baz\n', - 'f.js': '\n'.join([ + 'objdir/baz.js': 'baz\n', + 'srcdir/f.js': '\n'.join([ '#include foo.js', '#filter substitution', '#define inc bar.js', '#include test.js', - '#include baz.js', + '#include ../objdir/baz.js', 'fin', '', ]), } + preprocessed = ('//@line 1 "$SRCDIR/foo.js"\n' + 'bazfoobar\n' + '//@line 2 "$SRCDIR/bar.js"\n' + '@foo@\n' + '//@line 3 "$SRCDIR/foo.js"\n' + 'bazbarfoo\n' + '//@line 2 "$SRCDIR/bar.js"\n' + 'foobarbaz\n' + '//@line 3 "$SRCDIR/test.js"\n' + 'barfoobaz\n' + '//@line 1 "$OBJDIR/baz.js"\n' + 'baz\n' + '//@line 6 "$SRCDIR/f.js"\n' + 'fin\n').replace('DIR/', 'DIR' + os.sep) + + # Try with separate srcdir/objdir with MockedOpen(files): - self.pp.do_include('f.js') - self.assertEqual(self.pp.out.getvalue(), - ('//@line 1 "CWD/foo.js"\n' - 'bazfoobar\n' - '//@line 2 "CWD/bar.js"\n' - '@foo@\n' - '//@line 3 "CWD/foo.js"\n' - 'bazbarfoo\n' - '//@line 2 "CWD/bar.js"\n' - 'foobarbaz\n' - '//@line 3 "CWD/test.js"\n' - 'barfoobaz\n' - '//@line 1 "CWD/baz.js"\n' - 'baz\n' - '//@line 6 "CWD/f.js"\n' - 'fin\n').replace('CWD/', - os.getcwd() + os.path.sep)) + self.pp.topsrcdir = os.path.abspath('srcdir') + self.pp.topobjdir = os.path.abspath('objdir') + self.pp.do_include('srcdir/f.js') + self.assertEqual(self.pp.out.getvalue(), preprocessed) + + # Try again with relative objdir + self.setUp() + files['srcdir/objdir/baz.js'] = files['objdir/baz.js'] + del files['objdir/baz.js'] + files['srcdir/f.js'] = files['srcdir/f.js'].replace('../', '') + with MockedOpen(files): + self.pp.topsrcdir = os.path.abspath('srcdir') + self.pp.topobjdir = os.path.abspath('srcdir/objdir') + self.pp.do_include('srcdir/f.js') + self.assertEqual(self.pp.out.getvalue(), preprocessed) def test_include_missing_file(self): with MockedOpen({'f': '#include foo\n'}): diff --git a/python/mozbuild/mozpack/packager/__init__.py b/python/mozbuild/mozpack/packager/__init__.py index 5cd99056ac33..4b9126e44db4 100644 --- a/python/mozbuild/mozpack/packager/__init__.py +++ b/python/mozbuild/mozpack/packager/__init__.py @@ -188,8 +188,7 @@ class PreprocessorOutputWrapper(object): self._pp = preprocessor def write(self, str): - file = os.path.normpath(os.path.abspath(self._pp.context['FILE'])) - with errors.context(file, self._pp.context['LINE']): + with errors.context(self._pp.context['FILE'], self._pp.context['LINE']): self._parser.handle_line(str) diff --git a/python/mozbuild/mozpack/test/test_packager.py b/python/mozbuild/mozpack/test/test_packager.py index f3df7b67b686..38204bdeec84 100644 --- a/python/mozbuild/mozpack/test/test_packager.py +++ b/python/mozbuild/mozpack/test/test_packager.py @@ -5,6 +5,7 @@ import unittest import mozunit import os +from buildconfig import topobjdir from mozpack.packager import ( preprocess_manifest, CallDeque, @@ -43,7 +44,7 @@ baz@SUFFIX@ class TestPreprocessManifest(unittest.TestCase): - MANIFEST_PATH = os.path.join(os.path.abspath(os.curdir), 'manifest') + MANIFEST_PATH = os.path.join('$OBJDIR', 'manifest') EXPECTED_LOG = [ ((MANIFEST_PATH, 2), 'add', '', 'bar/*'), @@ -68,6 +69,11 @@ class TestPreprocessManifest(unittest.TestCase): self.log.append(args) self.sink = MockSink() + self.cwd = os.getcwd() + os.chdir(topobjdir) + + def tearDown(self): + os.chdir(self.cwd) def test_preprocess_manifest(self): with MockedOpen({'manifest': MANIFEST}): diff --git a/taskcluster/taskgraph/actions/add_new_jobs.py b/taskcluster/taskgraph/actions/add_new_jobs.py index 4ac8a21b844b..332f82ae4a68 100644 --- a/taskcluster/taskgraph/actions/add_new_jobs.py +++ b/taskcluster/taskgraph/actions/add_new_jobs.py @@ -58,5 +58,13 @@ def add_new_jobs_action(parameters, graph_config, input, task_group_id, task_id) times = input.get('times', 1) for i in xrange(times): - create_tasks(to_run, full_task_graph, label_to_taskid, parameters, decision_task_id, i) + create_tasks( + graph_config, + to_run, + full_task_graph, + label_to_taskid, + parameters, + decision_task_id, + i, + ) combine_task_graph_files(list(range(times))) diff --git a/taskcluster/taskgraph/actions/add_talos.py b/taskcluster/taskgraph/actions/add_talos.py index e749894df4ec..663874c9f7cc 100644 --- a/taskcluster/taskgraph/actions/add_talos.py +++ b/taskcluster/taskgraph/actions/add_talos.py @@ -48,5 +48,12 @@ def add_all_talos(parameters, graph_config, input, task_group_id, task_id): for label, entry in full_task_graph.tasks.iteritems() if 'talos_try_name' in entry.attributes] - create_tasks(to_run, full_task_graph, label_to_taskid, parameters, decision_task_id) + create_tasks( + graph_config, + to_run, + full_task_graph, + label_to_taskid, + parameters, + decision_task_id, + ) logger.info('Scheduled {} talos tasks (time {}/{})'.format(len(to_run), i+1, times)) diff --git a/taskcluster/taskgraph/actions/backfill.py b/taskcluster/taskgraph/actions/backfill.py index 910af7ab5670..82a83dfc525e 100644 --- a/taskcluster/taskgraph/actions/backfill.py +++ b/taskcluster/taskgraph/actions/backfill.py @@ -184,7 +184,7 @@ def backfill_action(parameters, graph_config, input, task_group_id, task_id): times = input.get('times', 1) for i in xrange(times): - create_tasks([label], full_task_graph, label_to_taskid, + create_tasks(graph_config, [label], full_task_graph, label_to_taskid, push_params, push_decision_task_id, push, modifier=modifier) backfill_pushes.append(push) else: diff --git a/taskcluster/taskgraph/actions/create_interactive.py b/taskcluster/taskgraph/actions/create_interactive.py index 9b83e44f9d0a..827fd360f1cc 100644 --- a/taskcluster/taskgraph/actions/create_interactive.py +++ b/taskcluster/taskgraph/actions/create_interactive.py @@ -149,7 +149,7 @@ def create_interactive_action(parameters, graph_config, input, task_group_id, ta # Create the task and any of its dependencies. This uses a new taskGroupId to avoid # polluting the existing taskGroup with interactive tasks. - label_to_taskid = create_tasks([label], full_task_graph, label_to_taskid, + label_to_taskid = create_tasks(graph_config, [label], full_task_graph, label_to_taskid, parameters, modifier=edit) taskId = label_to_taskid[label] diff --git a/taskcluster/taskgraph/actions/gecko_profile.py b/taskcluster/taskgraph/actions/gecko_profile.py index 0afa61823283..ac6c14ebc019 100644 --- a/taskcluster/taskgraph/actions/gecko_profile.py +++ b/taskcluster/taskgraph/actions/gecko_profile.py @@ -89,7 +89,7 @@ def geckoprofile_action(parameters, graph_config, input, task_group_id, task_id) task.task['extra']['treeherder']['symbol'] += '-p' return task - create_tasks([label], full_task_graph, label_to_taskid, + create_tasks(graph_config, [label], full_task_graph, label_to_taskid, push_params, push_decision_task_id, push, modifier=modifier) backfill_pushes.append(push) else: diff --git a/taskcluster/taskgraph/actions/retrigger.py b/taskcluster/taskgraph/actions/retrigger.py index f1954d64de65..42f1dfecc745 100644 --- a/taskcluster/taskgraph/actions/retrigger.py +++ b/taskcluster/taskgraph/actions/retrigger.py @@ -101,7 +101,15 @@ def retrigger_action(parameters, graph_config, input, task_group_id, task_id): times = input.get('times', 1) for i in xrange(times): - create_tasks(to_run, full_task_graph, label_to_taskid, parameters, decision_task_id, i) + create_tasks( + graph_config, + to_run, + full_task_graph, + label_to_taskid, + parameters, + decision_task_id, + i, + ) logger.info('Scheduled {}{}(time {}/{})'.format(label, with_downstream, i+1, times)) combine_task_graph_files(list(range(times))) diff --git a/taskcluster/taskgraph/actions/run_missing_tests.py b/taskcluster/taskgraph/actions/run_missing_tests.py index 6b5fa1c81c1c..ab73183376aa 100644 --- a/taskcluster/taskgraph/actions/run_missing_tests.py +++ b/taskcluster/taskgraph/actions/run_missing_tests.py @@ -49,7 +49,14 @@ def run_missing_tests(parameters, graph_config, input, task_group_id, task_id): continue to_run.append(label) - create_tasks(to_run, full_task_graph, label_to_taskid, parameters, decision_task_id) + create_tasks( + graph_config, + to_run, + full_task_graph, + label_to_taskid, + parameters, + decision_task_id, + ) logger.info('Out of {} test tasks, {} already existed and the action created {}'.format( already_run + len(to_run), already_run, len(to_run))) diff --git a/taskcluster/taskgraph/actions/util.py b/taskcluster/taskgraph/actions/util.py index 75f6b2ba8c90..d96e981f4e52 100644 --- a/taskcluster/taskgraph/actions/util.py +++ b/taskcluster/taskgraph/actions/util.py @@ -133,7 +133,7 @@ def update_parent(task, graph): return task -def create_tasks(to_run, full_task_graph, label_to_taskid, +def create_tasks(graph_config, to_run, full_task_graph, label_to_taskid, params, decision_task_id=None, suffix='', modifier=lambda t: t): """Create new tasks. The task definition will have {relative-datestamp': '..'} rendered just like in a decision task. Action callbacks should use @@ -173,7 +173,13 @@ def create_tasks(to_run, full_task_graph, label_to_taskid, write_artifact('task-graph{}.json'.format(suffix), optimized_task_graph.to_json()) write_artifact('label-to-taskid{}.json'.format(suffix), label_to_taskid) write_artifact('to-run{}.json'.format(suffix), list(to_run)) - create.create_tasks(optimized_task_graph, label_to_taskid, params, decision_task_id) + create.create_tasks( + graph_config, + optimized_task_graph, + label_to_taskid, + params, + decision_task_id, + ) return label_to_taskid diff --git a/taskcluster/taskgraph/create.py b/taskcluster/taskgraph/create.py index 3dc4ba9aae3a..d5708c695db4 100644 --- a/taskcluster/taskgraph/create.py +++ b/taskcluster/taskgraph/create.py @@ -21,7 +21,7 @@ logger = logging.getLogger(__name__) testing = False -def create_tasks(taskgraph, label_to_taskid, params, decision_task_id=None): +def create_tasks(graph_config, taskgraph, label_to_taskid, params, decision_task_id=None): taskid_to_label = {t: l for l, t in label_to_taskid.iteritems()} decision_task_id = decision_task_id or os.environ.get('TASK_ID') @@ -31,7 +31,7 @@ def create_tasks(taskgraph, label_to_taskid, params, decision_task_id=None): # helpfully placed it in this same taskGroup. If there is no $TASK_ID, # fall back to a slugid task_group_id = decision_task_id or slugid() - scheduler_id = 'gecko-level-{}'.format(params['level']) + scheduler_id = '{}-level-{}'.format(graph_config['trust-domain'], params['level']) # Add the taskGroupId, schedulerId and optionally the decision task # dependency diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py index 95e64534e4b7..5f86a177d664 100644 --- a/taskcluster/taskgraph/decision.py +++ b/taskcluster/taskgraph/decision.py @@ -188,7 +188,7 @@ def taskgraph_decision(options, parameters=None): write_artifact('label-to-taskid.json', tgg.label_to_taskid) # actually create the graph - create_tasks(tgg.morphed_task_graph, tgg.label_to_taskid, tgg.parameters) + create_tasks(tgg.graph_config, tgg.morphed_task_graph, tgg.label_to_taskid, tgg.parameters) def get_decision_parameters(config, options): diff --git a/taskcluster/taskgraph/test/test_create.py b/taskcluster/taskgraph/test/test_create.py index fed21d202a57..cb3354bea270 100644 --- a/taskcluster/taskgraph/test/test_create.py +++ b/taskcluster/taskgraph/test/test_create.py @@ -9,12 +9,15 @@ import os import mock from taskgraph import create +from taskgraph.config import GraphConfig from taskgraph.graph import Graph from taskgraph.taskgraph import TaskGraph from taskgraph.task import Task from mozunit import main +GRAPH_CONFIG = GraphConfig({'trust-domain': 'domain'}, '/var/empty') + class TestCreate(unittest.TestCase): @@ -45,11 +48,11 @@ class TestCreate(unittest.TestCase): graph = Graph(nodes={'tid-a', 'tid-b'}, edges={('tid-a', 'tid-b', 'edge')}) taskgraph = TaskGraph(tasks, graph) - create.create_tasks(taskgraph, label_to_taskid, {'level': '4'}) + create.create_tasks(GRAPH_CONFIG, taskgraph, label_to_taskid, {'level': '4'}) for tid, task in self.created_tasks.iteritems(): self.assertEqual(task['payload'], 'hello world') - self.assertEqual(task['schedulerId'], 'gecko-level-4') + self.assertEqual(task['schedulerId'], 'domain-level-4') # make sure the dependencies exist, at least for depid in task.get('dependencies', []): if depid is 'decisiontask': @@ -67,7 +70,7 @@ class TestCreate(unittest.TestCase): graph = Graph(nodes={'tid-a'}, edges=set()) taskgraph = TaskGraph(tasks, graph) - create.create_tasks(taskgraph, label_to_taskid, {'level': '4'}) + create.create_tasks(GRAPH_CONFIG, taskgraph, label_to_taskid, {'level': '4'}) for tid, task in self.created_tasks.iteritems(): self.assertEqual(task.get('dependencies'), [os.environ['TASK_ID']]) @@ -89,7 +92,7 @@ class TestCreate(unittest.TestCase): create_task.side_effect = fail with self.assertRaises(RuntimeError): - create.create_tasks(taskgraph, label_to_taskid, {'level': '4'}) + create.create_tasks(GRAPH_CONFIG, taskgraph, label_to_taskid, {'level': '4'}) if __name__ == '__main__': diff --git a/taskcluster/taskgraph/transforms/docker_image.py b/taskcluster/taskgraph/transforms/docker_image.py index d101f3c3b39d..f2b882d452e1 100644 --- a/taskcluster/taskgraph/transforms/docker_image.py +++ b/taskcluster/taskgraph/transforms/docker_image.py @@ -218,7 +218,7 @@ def fill_template(config, tasks): worker['caches'] = [{ 'type': 'persistent', - 'name': 'level-{}-{}'.format(config.params['level'], cache_name), + 'name': cache_name, 'mount-point': '/builds/worker/checkouts', }] diff --git a/taskcluster/taskgraph/transforms/job/common.py b/taskcluster/taskgraph/transforms/job/common.py index c53705c01897..960d3087334b 100644 --- a/taskcluster/taskgraph/transforms/job/common.py +++ b/taskcluster/taskgraph/transforms/job/common.py @@ -59,8 +59,8 @@ def docker_worker_add_workspace_cache(config, job, taskdesc, extra=None): extra (str): Optional context passed in that supports extending the cache key name to avoid undesired conflicts with other caches. """ - cache_name = 'level-{}-{}-build-{}-{}-workspace'.format( - config.params['level'], config.params['project'], + cache_name = '{}-build-{}-{}-workspace'.format( + config.params['project'], taskdesc['attributes']['build_platform'], taskdesc['attributes']['build_type'], ) @@ -120,12 +120,7 @@ def support_vcs_checkout(config, job, taskdesc, sparse=False): geckodir = '{}/gecko'.format(checkoutdir) hgstore = '{}/hg-store'.format(checkoutdir) - cache_name = 'level-{}-checkouts'.format(config.params['level']) - - # comm-central checkouts need their own cache, because clobber won't - # remove the comm-central checkout - if job['run'].get('comm-checkout', False): - cache_name += '-comm' + cache_name = 'checkouts' # Sparse checkouts need their own cache because they can interfere # with clients that aren't sparse aware. @@ -227,7 +222,7 @@ def docker_worker_add_tooltool(config, job, taskdesc, internal=False): assert job['worker']['implementation'] in ('docker-worker',) level = config.params['level'] - add_cache(job, taskdesc, 'level-{}-tooltool-cache'.format(level), + add_cache(job, taskdesc, 'tooltool-cache'.format(level), '{workdir}/tooltool-cache'.format(**job['run'])) taskdesc['worker'].setdefault('env', {}).update({ diff --git a/taskcluster/taskgraph/transforms/job/run_task.py b/taskcluster/taskgraph/transforms/job/run_task.py index cd67d8c050b9..93bd2aef0ad6 100644 --- a/taskcluster/taskgraph/transforms/job/run_task.py +++ b/taskcluster/taskgraph/transforms/job/run_task.py @@ -100,7 +100,7 @@ def docker_worker_run_task(config, job, taskdesc): if run.get('cache-dotcache'): worker['caches'].append({ 'type': 'persistent', - 'name': 'level-{level}-{project}-dotcache'.format(**config.params), + 'name': '{project}-dotcache'.format(**config.params), 'mount-point': '{workdir}/.cache'.format(**run), 'skip-untrusted': True, }) @@ -136,7 +136,7 @@ def generic_worker_run_task(config, job, taskdesc): worker.setdefault('mounts', []) if run.get('cache-dotcache'): worker['mounts'].append({ - 'cache-name': 'level-{level}-{project}-dotcache'.format(**config.params), + 'cache-name': '{project}-dotcache'.format(**config.params), 'directory': '{workdir}/.cache'.format(**run), }) worker['mounts'].append({ diff --git a/taskcluster/taskgraph/transforms/job/spidermonkey.py b/taskcluster/taskgraph/transforms/job/spidermonkey.py index d44396cdd640..195ae261b6cb 100644 --- a/taskcluster/taskgraph/transforms/job/spidermonkey.py +++ b/taskcluster/taskgraph/transforms/job/spidermonkey.py @@ -44,8 +44,7 @@ def docker_worker_spidermonkey(config, job, taskdesc): worker['artifacts'] = [] worker.setdefault('caches', []).append({ 'type': 'persistent', - 'name': 'level-{}-{}-build-spidermonkey-workspace'.format( - config.params['level'], config.params['project']), + 'name': '{}-build-spidermonkey-workspace'.format(config.params['project']), 'mount-point': "{workdir}/workspace".format(**run), 'skip-untrusted': True, }) diff --git a/taskcluster/taskgraph/transforms/task.py b/taskcluster/taskgraph/transforms/task.py index fe61012f34e3..721a2ae09248 100644 --- a/taskcluster/taskgraph/transforms/task.py +++ b/taskcluster/taskgraph/transforms/task.py @@ -625,14 +625,14 @@ def build_docker_worker_payload(config, task, task_def): cache_version = 'v3' if run_task: - suffix = '-%s-%s' % (cache_version, _run_task_suffix()) + suffix = '{}-{}'.format(cache_version, _run_task_suffix()) if out_of_tree_image: name_hash = hashlib.sha256(out_of_tree_image).hexdigest() suffix += name_hash[0:12] else: - suffix = '-%s' % cache_version + suffix = cache_version skip_untrusted = config.params.is_try() or level == 1 @@ -642,7 +642,13 @@ def build_docker_worker_payload(config, task, task_def): if cache.get('skip-untrusted') and skip_untrusted: continue - name = '%s%s' % (cache['name'], suffix) + name = '{trust_domain}-level-{level}-{name}-{suffix}'.format( + trust_domain=config.graph_config['trust-domain'], + level=config.params['level'], + name=cache['name'], + suffix=suffix, + ) + caches[name] = cache['mount-point'] task_def['scopes'].append('docker-worker:cache:%s' % name) @@ -803,7 +809,11 @@ def build_generic_worker_payload(config, task, task_def): mounts = deepcopy(worker.get('mounts', [])) for mount in mounts: if 'cache-name' in mount: - mount['cacheName'] = mount.pop('cache-name') + mount['cacheName'] = '{trust_domain}-level-{level}-{name}'.format( + trust_domain=config.graph_config['trust-domain'], + level=config.params['level'], + name=mount.pop('cache-name'), + ) task_def['scopes'].append('generic-worker:cache:{}'.format(mount['cacheName'])) if 'content' in mount: if 'task-id' in mount['content']: @@ -1845,10 +1855,15 @@ def check_run_task_caches(config, tasks): THAT RUN-TASK ALREADY SOLVES. THINK LONG AND HARD BEFORE DOING THAT. """ re_reserved_caches = re.compile('''^ - (level-\d+-checkouts|level-\d+-tooltool-cache) + (checkouts|tooltool-cache) ''', re.VERBOSE) - re_sparse_checkout_cache = re.compile('^level-\d+-checkouts-sparse') + re_sparse_checkout_cache = re.compile('^checkouts-sparse') + + cache_prefix = '{trust_domain}-level-{level}-'.format( + trust_domain=config.graph_config['trust-domain'], + level=config.params['level'], + ) suffix = _run_task_suffix() @@ -1886,6 +1901,15 @@ def check_run_task_caches(config, tasks): break for cache in payload.get('cache', {}): + if not cache.startswith(cache_prefix): + raise Exception( + '{} is using a cache ({}) which is not appropriate ' + 'for its trust-domain and level. It should start with {}.' + .format(task['label'], cache, cache_prefix) + ) + + cache = cache[len(cache_prefix):] + if re_sparse_checkout_cache.match(cache): have_sparse_cache = True diff --git a/testing/web-platform/meta/editing/run/justifycenter.html.ini b/testing/web-platform/meta/editing/run/justifycenter.html.ini index 4e2549cd2934..d65bd3656bea 100644 --- a/testing/web-platform/meta/editing/run/justifycenter.html.ini +++ b/testing/web-platform/meta/editing/run/justifycenter.html.ini @@ -1465,6 +1465,7 @@ [justifycenter.html?1-1000] + max-asserts: 8 [[["stylewithcss","false"\],["defaultparagraphseparator","div"\],["justifycenter",""\]\] "foo[\]bar

extra" compare innerHTML] expected: FAIL @@ -1575,6 +1576,7 @@ [justifycenter.html?4001-5000] + max-asserts: 8 [[["stylewithcss","false"\],["defaultparagraphseparator","div"\],["justifycenter",""\]\] "

foo

[bar\]

baz

extra" queryCommandState("justifycenter") after] expected: FAIL @@ -1832,6 +1834,7 @@ [justifycenter.html?6001-last] + max-asserts: 8 [[["stylewithcss","false"\],["defaultparagraphseparator","p"\],["justifycenter",""\]\] "

foo

[bar\]

baz

" compare innerHTML] expected: FAIL @@ -1861,6 +1864,7 @@ [justifycenter.html?2001-3000] + max-asserts: 8 [[["stylewithcss","true"\],["defaultparagraphseparator","p"\],["justifycenter",""\]\] "
foobarbaz

extra" queryCommandValue("defaultparagraphseparator") after] expected: FAIL @@ -2268,6 +2272,7 @@ [justifycenter.html?3001-4000] + max-asserts: 8 [[["stylewithcss","false"\],["defaultparagraphseparator","p"\],["justifycenter",""\]\] "

[foo\]

bar

extra" queryCommandState("justifycenter") after] expected: FAIL @@ -2414,6 +2419,7 @@ [justifycenter.html?5001-6000] + max-asserts: 8 [[["stylewithcss","true"\],["defaultparagraphseparator","div"\],["justifycenter",""\]\] "

{
foo
}
" queryCommandState("justifycenter") before] expected: FAIL @@ -2770,6 +2776,7 @@ [justifycenter.html?1001-2000] + max-asserts: 8 [[["stylewithcss","false"\],["defaultparagraphseparator","p"\],["justifycenter",""\]\] "

[foo

bar\]

extra" compare innerHTML] expected: FAIL diff --git a/testing/web-platform/meta/service-workers/service-worker/navigation-redirect.https.html.ini b/testing/web-platform/meta/service-workers/service-worker/navigation-redirect.https.html.ini index 1a16deefd2e2..4edce167ba53 100644 --- a/testing/web-platform/meta/service-workers/service-worker/navigation-redirect.https.html.ini +++ b/testing/web-platform/meta/service-workers/service-worker/navigation-redirect.https.html.ini @@ -6,6 +6,8 @@ [navigation-redirect.https.html?client] disabled: if os == "mac": true + if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1522439 + if debug and os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1522439 [Redirect to same-origin out-scope with opaque redirect response.] expected: FAIL @@ -19,9 +21,6 @@ expected: FAIL [SW-fallbacked redirect to same-origin out-scope.] - disabled: - if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1522439 - if debug and os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1522439 expected: FAIL [SW-fetched redirect to same-origin out-scope.] diff --git a/testing/web-platform/meta/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html.ini b/testing/web-platform/meta/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html.ini index 9b681605183c..d016015a9f48 100644 --- a/testing/web-platform/meta/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html.ini +++ b/testing/web-platform/meta/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html.ini @@ -1,22 +1,10 @@ [audioworkletnode-construction.https.html] expected: if release_or_beta: ERROR - [X Unregistered name "foobar" must throw an exception. did not throw an exception.] - expected: FAIL - - [< [construction-after-module-loading\] 1 out of 2 assertions were failed.] - expected: FAIL - [< [construction-before-module-loading\] 1 out of 1 assertions were failed.] - expected: FAIL - + expected: + if release_or_beta: FAIL [X Creating a node before loading a module should throw. threw "ReferenceError" instead of InvalidStateError.] expected: if release_or_beta: FAIL - [X Creating a node before loading a module should throw. did not throw an exception.] - expected: FAIL - - [# AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed.] - expected: FAIL - diff --git a/testing/web-platform/mozilla/tests/focus/Range_collapse.html b/testing/web-platform/mozilla/tests/focus/Range_collapse.html index df6218d9f0f4..7c16f16bec58 100644 --- a/testing/web-platform/mozilla/tests/focus/Range_collapse.html +++ b/testing/web-platform/mozilla/tests/focus/Range_collapse.html @@ -4,6 +4,7 @@ +

Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Range.collapse(true) of selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -78,6 +81,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Range.collapse(false) of selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -85,6 +89,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Range.collapse(false) of selection between start of the first text node of 'staticBefore' and end of the first text node of 'anchor' when active element is the "); test(function() { resetFocusAndSelectionRange(editor); @@ -92,6 +97,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Range.collapse(false) of selection between start of the first text node of 'editor' and end of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -99,6 +105,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Range.collapse(true) of selection between start of the first text node of 'editor' and end of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -106,6 +113,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Range.collapse(false) of selection between start of the first text node of 'innerEditor' and end of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -113,6 +121,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Range.collapse(true) of selection between start of the first text node of 'innerEditor' and end of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -120,6 +129,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Range.collapse(false) of selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -127,6 +137,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Range.collapse(true) of selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' when active element is 'anchor'"); test(function() { @@ -135,6 +146,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Range.collapse(true) of selection between start of the first text node of 'staticBefore' and end of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -142,6 +154,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Range.collapse(false) of selection between start of the first text node of 'staticBefore' and end of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -149,6 +162,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Range.collapse(true) of selection between start of the first text node of 'editor' and end of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -156,6 +170,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Range.collapse(false) of selection between start of the first text node of 'editor' and end of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -163,6 +178,7 @@ test(function() { staticInEditor.textNode, staticInEditor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Range.collapse(true) of selection between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -170,6 +186,7 @@ test(function() { staticInEditor.textNode, staticInEditor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Range.collapse(false) of selection between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -177,6 +194,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().getRangeAt(0).collapse(true); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Range.collapse(true) of selection between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -184,5 +202,6 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().getRangeAt(0).collapse(false); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Range.collapse(false) of selection between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' when active element is 'outerEditor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Range_selectNode.html b/testing/web-platform/mozilla/tests/focus/Range_selectNode.html index 5c8f59a04b77..3975653d2c12 100644 --- a/testing/web-platform/mozilla/tests/focus/Range_selectNode.html +++ b/testing/web-platform/mozilla/tests/focus/Range_selectNode.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after " + aTest.doingDescription + " with the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); aTest.func(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); aTest.func(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); aTest.func(staticInEditor.textNode); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); aTest.func(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); aTest.func(anchor.textNode); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with the first text node of 'anchor' when active element is the "); test(function() { resetFocusAndSelectionRange(editor); aTest.func(staticBefore.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); aTest.func(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); aTest.func(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); aTest.func(staticInEditor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); aTest.func(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); aTest.func(anchor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'anchor' when active element is the 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(staticBefore.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(staticInEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); aTest.func(anchor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'anchor' when active element is the 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(staticBefore.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(staticInEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); aTest.func(anchor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'anchor' when active element is the 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(staticBefore.textNode); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after " + aTest.doingDescription + " with the first text node of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with the first text node of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with the first text node of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(staticInEditor.textNode); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after " + aTest.doingDescription + " with the first text node of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with the first text node of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); aTest.func(anchor.textNode); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after " + aTest.doingDescription + " with the first text node of 'anchor' when active element is the 'anchor'"); }); diff --git a/testing/web-platform/mozilla/tests/focus/Range_setEnd.html b/testing/web-platform/mozilla/tests/focus/Range_setEnd.html index ec0086b87c4d..e1eed4ae717f 100644 --- a/testing/web-platform/mozilla/tests/focus/Range_setEnd.html +++ b/testing/web-platform/mozilla/tests/focus/Range_setEnd.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (before the selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(anchor.textNode); aTest.func(staticAfter.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after " + aTest.doingDescription + " with start of the first text node of 'staticAfter' (before the selection) when active element is 'anchor'"); test(function() { @@ -119,42 +126,49 @@ function setEndAfter(aNode, aOffset) document.getSelection().collapse(staticBefore.textNode, staticBefore.textLength); aTest.func(staticBefore.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with start of the first text node of 'staticBefore' (before the collapsed selection) when active element is the "); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().collapse(editor.textNode, editor.textLength); aTest.func(staticBefore.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'staticBefore' (before the collapsed selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, outerEditor.textLength); aTest.func(editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'editor' (before the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(staticInEditor.textNode, staticInEditor.textLength); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (before the collapsed selection) when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(innerEditor.textNode, innerEditor.textLength); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (before the collapsed selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().collapse(anchor.textNode, anchor.textLength); aTest.func(staticAfter.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after " + aTest.doingDescription + " with start of the first text node of 'staticAfter' (before the collapsed selection) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(anchor.textNode, anchor.textLength); aTest.func(anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with start of the first text node of 'anchor' (before the collapsed selection) when active element is the "); test(function() { @@ -163,6 +177,7 @@ function setEndAfter(aNode, aOffset) editor.textNode, editor.textLength); aTest.func(staticBefore.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with start of the first text node of 'staticBefore' (before the selection, between end of the first text node of 'staticBefore' and end of the first text node of 'editor') when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -170,6 +185,7 @@ function setEndAfter(aNode, aOffset) outerEditor.textNode, outerEditor.textLength); aTest.func(editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'editor' (before the selection, between end of the first text node of 'editor' and end of the first text node of 'outerEditor') when active element is the "); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -177,6 +193,7 @@ function setEndAfter(aNode, aOffset) innerEditor.textNode, innerEditor.textLength); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (before the selection, between end of the first text node of 'outerEditor' and end of the first text node of 'innerEditor') when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); @@ -184,6 +201,7 @@ function setEndAfter(aNode, aOffset) innerEditor.textNode, innerEditor.textLength); aTest.func(staticInEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with start of the first text node of 'staticInEditor' (before the selection, between end of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor') when active element is the "); }); @@ -192,42 +210,49 @@ test(function() { document.getSelection().selectAllChildren(staticAfter.textNode); setEndAfter(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setEndAfter() with the first text node of 'innerEditor' (before the selection) when active element is the and selection is in 'staticAfter'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); setEndAfter(staticInEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setEndAfter() with the first text node of 'staticInEditor' (before the selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(staticInEditor.textNode); setEndAfter(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setEndAfter() with the first text node of 'outerEditor' (before the selection) when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); setEndAfter(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setEndAfter() with the first text node of 'outerEditor' (before the selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); setEndAfter(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setEndAfter() with the first text node of 'editor' (before the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(editor.textNode); setEndAfter(staticBefore.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setEndAfter() with the first text node of 'staticBefore' (before the selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(anchor.textNode); setEndAfter(staticBefore.textNode); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setEndAfter() with the first text node of 'staticBefore' (before the selection) when active element is 'anchor'"); // Range.setEnd*() should blur focused editing host when it expands selection to outside of it. @@ -239,48 +264,56 @@ test(function() { document.getSelection().collapse(editor.textNode, 0); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (after end of the collapsed selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, 0); aTest.func(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (after end of the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, 0); aTest.func(innerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'innerEditor' (after end of the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, 0); aTest.func(staticAfter.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'staticAfter' (after end of the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(editor.textNode); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (after end of the selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); aTest.func(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (after end of the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); aTest.func(innerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'innerEditor' (after end of the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); aTest.func(staticAfter.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'staticAfter' (after end of the selection) when active element is 'outerEditor'"); }); @@ -293,6 +326,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); aTest.func(editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with end of the first text node of 'editor' (shrunken into 'editor') when active element is the "); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -300,6 +334,7 @@ test(function() { staticInEditor.textNode, staticInEditor.textLength); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (shrunken into 'outerEditor') when active element is 'outerEditor' and selection end is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -307,6 +342,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (shrunken into 'outerEditor') when active element is 'outerEditor' and selection end is in 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); @@ -314,6 +350,7 @@ test(function() { staticAfter.textNode, staticAfter.textLength); aTest.func(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'innerEditor' (shrunken into 'innerEditor') when active element is 'innerEditor' and selection end is in 'staticAfter'"); test(function() { resetFocusAndSelectionRange(); @@ -321,6 +358,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (shrunken into 'staticInEditor') when active element is the "); }); diff --git a/testing/web-platform/mozilla/tests/focus/Range_setStart.html b/testing/web-platform/mozilla/tests/focus/Range_setStart.html index 5d8afa26310c..9297aa02abdb 100644 --- a/testing/web-platform/mozilla/tests/focus/Range_setStart.html +++ b/testing/web-platform/mozilla/tests/focus/Range_setStart.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(editor.textNode); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (before the selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (before the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(staticInEditor.textNode); aTest.func(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'innerEditor' (before the selection) when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); aTest.func(staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticAfter' (before the selection) when active element is 'innerEditor'"); test(function() { @@ -119,30 +126,35 @@ function setStartAfter(aNode, aOffset) document.getSelection().collapse(staticBefore.textNode, 0); aTest.func(editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with end of the first text node of 'editor' (before the collapsed selection) when active element is the "); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().collapse(editor.textNode, 0); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (before the collapsed selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, 0); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (before the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(staticInEditor.textNode, 0); aTest.func(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'innerEditor' (before the collapsed selection) when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(innerEditor.textNode, 0); aTest.func(staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticAfter' (before the collapsed selection) when active element is 'innerEditor'"); test(function() { @@ -151,6 +163,7 @@ function setStartAfter(aNode, aOffset) editor.textNode, 0); aTest.func(editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with end of the first text node of 'editor' (before the selection, between start of the first text node of 'staticBefore' and start of the first text node of 'editor') when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -158,6 +171,7 @@ function setStartAfter(aNode, aOffset) outerEditor.textNode, 0); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (before the selection, between start of the first text node of 'editor' and start of the first text node of 'outerEditor') when active element is the "); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -165,6 +179,7 @@ function setStartAfter(aNode, aOffset) staticInEditor.textNode, 0); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (before the selection, between start of the first text node of 'outerEditor' and start of the first text node of 'staticInEditor') when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -172,6 +187,7 @@ function setStartAfter(aNode, aOffset) innerEditor.textNode, 0); aTest.func(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'innerEditor' (before the selection, between start of the first text node of 'outerEditor' and start of the first text node of 'innerEditor') when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); @@ -179,6 +195,7 @@ function setStartAfter(aNode, aOffset) innerEditor.textNode, 0); aTest.func(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'innerEditor' (before the selection, between start of the first text node of 'staticInEditor' and start of the first text node of 'innerEditor') when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -186,6 +203,7 @@ function setStartAfter(aNode, aOffset) staticAfter.textNode, 0); aTest.func(staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with end of the first text node of 'staticAfter' (before the selection, between start of the first text node of 'innerEditor' and start of the first text node of 'staticAfter') when active element is the "); }); @@ -194,30 +212,35 @@ test(function() { document.getSelection().selectAllChildren(staticBefore.textNode); setStartBefore(editor.textNode); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Range.setStartBefore() with the first text node of 'editor' (before the selection) when active element is the "); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(editor.textNode); setStartBefore(outerEditor.textNode); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Range.setStartBefore() with the first text node of 'outerEditor' (before the selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); setStartBefore(innerEditor.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Range.setStartBefore() with the first text node of 'innerEditor' (before the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); setStartBefore(staticAfter.textNode); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Range.setStartBefore() with the first text node of 'innerEditor' (before the selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(staticAfter.textNode); setStartBefore(anchor.textNode); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Range.setStartBefore() with the first text node of 'anchor' (before the selection) when active element is the "); // Range.setStart*() should blur focused editing host when it expands selection to outside of it. @@ -229,24 +252,28 @@ test(function() { document.getSelection().collapse(editor.textNode, editor.textLength); aTest.func(staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with end of the first text node of 'staticBefore' (before the collapsed selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(outerEditor.textNode, outerEditor.textLength); aTest.func(editor.textNode, editor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'editor' (before the collapsed selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(innerEditor.textNode, innerEditor.textLength); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (before the collapsed selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(innerEditor.textNode, innerEditor.textLength); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (before the collapsed selection) when active element is 'innerEditor'"); test(function() { @@ -254,24 +281,28 @@ test(function() { document.getSelection().selectAllChildren(editor.textNode); aTest.func(staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with end of the first text node of 'staticBefore' (before the selection) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.textNode); aTest.func(editor.textNode, editor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'editor' (before the selection) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); aTest.func(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with end of the first text node of 'outerEditor' (before the selection) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.textNode); aTest.func(staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with end of the first text node of 'staticInEditor' (before the selection) when active element is 'innerEditor'"); }); @@ -284,6 +315,7 @@ test(function() { editor.textNode, editor.textLength); aTest.func(editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after " + aTest.doingDescription + " with start of the first text node of 'editor' (shrunken into 'editor') when active element is the "); test(function() { resetFocusAndSelectionRange(editor); @@ -291,6 +323,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); aTest.func(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'outerEditor' (shrunken into 'outerEditor') when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -298,6 +331,7 @@ test(function() { staticInEditor.textNode, staticInEditor.textLength); aTest.func(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after " + aTest.doingDescription + " with start of the first text node of 'staticInEditor' (shrunken into 'staticInEditor') when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -305,6 +339,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); aTest.func(innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after " + aTest.doingDescription + " with start of the first text node of 'innerEditor' (shrunken into 'innerEditor') when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); @@ -312,6 +347,7 @@ test(function() { anchor.textNode, anchor.textLength); aTest.func(anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after " + aTest.doingDescription + " with start of the first text node of 'anchor' (shrunken into 'anchor') when active element is the "); }); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_addRange.html b/testing/web-platform/mozilla/tests/focus/Selection_addRange.html index 80f33f6cf53a..d94e68815899 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_addRange.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_addRange.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -86,6 +89,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -94,6 +98,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -102,6 +107,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -110,6 +116,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -118,6 +125,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -126,6 +134,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is the "); test(function() { @@ -135,6 +144,7 @@ test(function() { range.setStart(staticBefore.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -143,6 +153,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -151,6 +162,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -159,6 +171,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -167,6 +180,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -175,6 +189,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -183,6 +198,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is 'editor'"); test(function() { @@ -192,6 +208,7 @@ test(function() { range.setStart(staticBefore.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -200,6 +217,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -208,6 +226,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -216,6 +235,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -224,6 +244,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -232,6 +253,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -240,6 +262,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is 'outerEditor'"); test(function() { @@ -249,6 +272,7 @@ test(function() { range.setStart(staticBefore.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -257,6 +281,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -265,6 +290,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -273,6 +299,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -281,6 +308,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -289,6 +317,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -297,6 +326,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is the and selection is in 'staticInEditor'"); test(function() { @@ -306,6 +336,7 @@ test(function() { range.setStart(staticBefore.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -314,6 +345,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -322,6 +354,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -330,6 +363,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -338,6 +372,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -346,6 +381,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -354,6 +390,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is 'innerEditor'"); test(function() { @@ -363,6 +400,7 @@ test(function() { range.setStart(staticBefore.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with collapsed range at start of the first text node of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -371,6 +409,7 @@ test(function() { range.setStart(editor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with collapsed range at start of the first text node of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -379,6 +418,7 @@ test(function() { range.setStart(outerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -387,6 +427,7 @@ test(function() { range.setStart(staticInEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -395,6 +436,7 @@ test(function() { range.setStart(innerEditor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with collapsed range at start of the first text node of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -403,6 +445,7 @@ test(function() { range.setStart(staticAfter.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with collapsed range at start of the first text node of 'staticAfter' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -411,6 +454,7 @@ test(function() { range.setStart(anchor.textNode, 0); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with collapsed range at start of the first text node of 'anchor' when active element is 'anchor'"); // Selection.addRange() with non-collapsed range in a node. @@ -422,6 +466,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -431,6 +476,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -440,6 +486,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -449,6 +496,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -458,6 +506,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -467,6 +516,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -476,6 +526,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is the "); test(function() { @@ -486,6 +537,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -495,6 +547,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -504,6 +557,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -513,6 +567,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -522,6 +577,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -531,6 +587,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -540,6 +597,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is 'editor'"); test(function() { @@ -550,6 +608,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -559,6 +618,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -568,6 +628,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -577,6 +638,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -586,6 +648,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -595,6 +658,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -604,6 +668,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is 'outerEditor'"); test(function() { @@ -614,6 +679,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -623,6 +689,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -632,6 +699,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -641,6 +709,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -650,6 +719,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -659,6 +729,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); @@ -668,6 +739,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { @@ -678,6 +750,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -687,6 +760,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -696,6 +770,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -705,6 +780,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -714,6 +790,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -723,6 +800,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -732,6 +810,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is 'innerEditor'"); test(function() { @@ -742,6 +821,7 @@ test(function() { range.setEnd(staticBefore.textNode, staticBefore.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in the first text node of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -751,6 +831,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range in start of the first text node of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -760,6 +841,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range in start of the first text node of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -769,6 +851,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -778,6 +861,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range in start of the first text node of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -787,6 +871,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'staticAfter' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -796,6 +881,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range in start of the first text node of 'anchor' when active element is 'anchor'"); // Selection.addRange() with a range across editing host boundary. @@ -807,6 +893,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -816,6 +903,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -825,6 +913,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -834,6 +923,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -843,6 +933,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -852,6 +943,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); @@ -861,6 +953,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is the "); test(function() { @@ -871,6 +964,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -880,6 +974,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -889,6 +984,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -898,6 +994,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -907,6 +1004,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -916,6 +1014,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -925,6 +1024,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'editor'"); test(function() { @@ -935,6 +1035,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -944,6 +1045,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -953,6 +1055,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -962,6 +1065,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -971,6 +1075,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -980,6 +1085,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -989,6 +1095,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'outerEditor'"); test(function() { @@ -999,6 +1106,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1008,6 +1116,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1017,6 +1126,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1026,6 +1136,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1035,6 +1146,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1044,6 +1156,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -1053,6 +1166,7 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'innerEditor'"); test(function() { @@ -1063,6 +1177,7 @@ test(function() { range.setEnd(editor.textNode, editor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1072,6 +1187,7 @@ test(function() { range.setEnd(outerEditor.textNode, outerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1081,6 +1197,7 @@ test(function() { range.setEnd(staticInEditor.textNode, staticInEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1090,6 +1207,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1099,6 +1217,7 @@ test(function() { range.setEnd(innerEditor.textNode, innerEditor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.addRange() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1108,6 +1227,7 @@ test(function() { range.setEnd(staticAfter.textNode, staticAfter.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -1117,5 +1237,6 @@ test(function() { range.setEnd(anchor.textNode, anchor.textLength); document.getSelection().addRange(range); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.addRange() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'anchor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_addRange_in_iframe.html b/testing/web-platform/mozilla/tests/focus/Selection_addRange_in_iframe.html index cccc395e1be5..71b7c26c46eb 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_addRange_in_iframe.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_addRange_in_iframe.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor
+
Spacer to check whether or not page was scrolled down to focused editor

Here is an iframe:

+
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.collapse() not moving selection from first text node in the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.collapse() moving selection from first text node in the to start of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapse() moving selection from first text node in the to start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(staticInEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.collapse() moving selection from first text node in the to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapse() moving selection from first text node in the to start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().collapse(anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.collapse() moving selection from first text node in the to start of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapse() moving selection from first text node in 'outerEditor' to start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().collapse(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapse() moving selection from first text node in 'outerEditor' to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(staticBefore.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapse() moving selection from first text node in 'innerEditor' to start of the first text node of the "); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.collapse() moving selection from first text node in 'innerEditor' to start of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapse() moving selection from first text node in 'innerEditor' to start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(staticInEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapse() moving selection from first text node in 'innerEditor' to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().collapse(anchor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapse() moving selection from first text node in 'innerEditor' to start of the first text node of 'anchor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_collapseToEnd.html b/testing/web-platform/mozilla/tests/focus/Selection_collapseToEnd.html index 7f3937e64cd7..f76878265064 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_collapseToEnd.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_collapseToEnd.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.collapseToEnd() with selection between start of the first text node of 'anchor' and end of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(); @@ -78,6 +81,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.collapseToEnd() with selection between start of the first text node of 'staticBefore' and end of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -85,6 +89,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.collapseToEnd() with selection between start of the first text node of 'editor' and end of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -92,6 +97,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapseToEnd() with selection between start of the first text node of 'innerEditor' and end of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -99,6 +105,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.collapseToEnd() with selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' and 'anchor' has focus before the call"); test(function() { resetFocusAndSelectionRange(); @@ -106,6 +113,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.collapseToEnd() with selection between start of the first text node of 'staticBefore' and end of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(); @@ -113,6 +121,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapseToEnd() with selection between start of the first text node of 'editor' and end of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -120,5 +129,6 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().collapseToEnd(); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapseToEnd() with selection between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_collapseToStart.html b/testing/web-platform/mozilla/tests/focus/Selection_collapseToStart.html index 9060f4e1733c..238a436c1bb2 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_collapseToStart.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_collapseToStart.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.collapseToStart() with selection between start of the first text node of 'anchor' and end of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(editor); @@ -78,6 +81,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.collapseToStart() with selection between start of the first text node of 'editor' and end of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(innerEditor); @@ -85,6 +89,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapseToStart() with selection between start of the first text node of 'innerEditor' and end of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); @@ -92,6 +97,7 @@ test(function() { anchor.textNode, anchor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.collapseToStart() with selection between start of the first text node of 'anchor' and end of the first text node of 'anchor' and 'anchor' has focus before the call"); test(function() { resetFocusAndSelectionRange(); @@ -99,6 +105,7 @@ test(function() { editor.textNode, editor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.collapseToStart() with selection between start of the first text node of 'staticBefore' and end of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(); @@ -106,6 +113,7 @@ test(function() { outerEditor.textNode, outerEditor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapseToStart() with selection between start of the first text node of 'editor' and end of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -113,6 +121,7 @@ test(function() { staticInEditor.textNode, staticInEditor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapseToStart() with selection between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); @@ -120,6 +129,7 @@ test(function() { innerEditor.textNode, innerEditor.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.collapseToStart() with selection between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); @@ -127,5 +137,6 @@ test(function() { staticAfter.textNode, staticAfter.textLength); document.getSelection().collapseToStart(); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.collapseToStart() with selection between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_extend.html b/testing/web-platform/mozilla/tests/focus/Selection_extend.html index 3a820d131463..62136cc4a3b2 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_extend.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_extend.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().extend(outerEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().extend(staticInEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().extend(innerEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().extend(staticAfter.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'staticAfter'"); test(function() { resetFocusAndSelectionRange(); document.getSelection().extend(anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'staticBefore' to start of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().extend(editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.extend() from selection at start of the first text node of 'editor' to end of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().extend(outerEditor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.extend() from selection at start of the first text node of 'editor' to start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().extend(innerEditor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.extend() from selection at start of the first text node of 'editor' to start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().extend(outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'outerEditor' to end of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().extend(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'outerEditor' to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().extend(innerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'outerEditor' to start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().extend(editor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'outerEditor' to start of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().extend(innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.extend() from selection at start of the first text node of 'innerEditor' to end of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().extend(outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'innerEditor' to start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().extend(staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.extend() from selection at start of the first text node of 'innerEditor' to start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().extend(anchor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.extend() from selection at start of the first text node of 'innerEditor' to start of the first text node of 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().extend(anchor.textNode, anchor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.extend() from selection at start of the first text node of 'anchor' to end of the first text node of 'anchor' and 'anchor' has focus before the call"); test(function() { resetFocusAndSelectionRange(anchor); anchor.element.blur(); document.getSelection().extend(anchor.textNode, anchor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.extend() from selection at start of the first text node of 'anchor' to end of the first text node of 'anchor' and 'anchor' doesn't have focus before the call"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_removeAllRanges.html b/testing/web-platform/mozilla/tests/focus/Selection_removeAllRanges.html index 4d0cf4c288a7..6e6854d44b97 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_removeAllRanges.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_removeAllRanges.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.removeAllRanges() when active element is the and selection is at the start of the first text node of 'staticBefore'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.removeAllRanges() when active element is 'editor' and selection is at the start of the first text node of 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.removeAllRanges() when active element is 'outerEditor' and selection is at the start of the first text node of 'outerEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.removeAllRanges() when active element is the and selection is at the start of the first text node of 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.removeAllRanges() when active element is 'innerEditor' and selection is at the start of the first text node of 'innerEditor'"); test(function() { resetFocusAndSelectionRange(staticAfter); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.removeAllRanges() when active element is the and selection is at the start of the first text node of 'staticAfter'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().removeAllRanges(); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.removeAllRanges() when active element is 'anchor' and selection is at the start of the first text node of 'anchor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_removeRange.html b/testing/web-platform/mozilla/tests/focus/Selection_removeRange.html index 40f6d0578b15..14e78381d2de 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_removeRange.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_removeRange.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.removeRange() to remove selected range at the start of the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.removeRange() to remove selected range at the start of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.removeRange() to remove selected range at the start of the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.removeRange() to remove selected range at the start of the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.removeRange() to remove selected range at the start of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(staticAfter); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.removeRange() to remove selected range at the start of the first text node of 'staticAfter' when active element is the "); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().removeRange(document.getSelection().getRangeAt(0)); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.removeRange() to remove selected range at the start of the first text node of 'anchor' when active element is 'anchor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_selectAllChildren.html b/testing/web-platform/mozilla/tests/focus/Selection_selectAllChildren.html index ca014b893ebc..2753e608511d 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_selectAllChildren.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_selectAllChildren.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.selectAllChildren() to select the children of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(editor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(outerEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(staticInEditor.element); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.selectAllChildren() to select the children of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(innerEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().selectAllChildren(anchor.element); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.selectAllChildren() to select the children of 'anchor' when active element is the "); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(staticBefore.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(editor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(outerEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(staticInEditor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(innerEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().selectAllChildren(anchor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'anchor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(staticBefore.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(editor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(outerEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(staticInEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'ouerEditor' after Selection.selectAllChildren() to select the children of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(innerEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().selectAllChildren(anchor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'anchor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(staticBefore.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(editor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(outerEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(staticInEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(innerEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().selectAllChildren(anchor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'anchor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(staticBefore.element); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.selectAllChildren() to select the children of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(editor.element); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.selectAllChildren() to select the children of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(outerEditor.element); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.selectAllChildren() to select the children of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(staticInEditor.element); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.selectAllChildren() to select the children of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(innerEditor.element); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.selectAllChildren() to select the children of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().selectAllChildren(anchor.element); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.selectAllChildren() to select the children of 'anchor' when active element is 'anchor'"); diff --git a/testing/web-platform/mozilla/tests/focus/Selection_setBaseAndExtent.html b/testing/web-platform/mozilla/tests/focus/Selection_setBaseAndExtent.html index 793fd3ada8f9..7cfc1100093d 100644 --- a/testing/web-platform/mozilla/tests/focus/Selection_setBaseAndExtent.html +++ b/testing/web-platform/mozilla/tests/focus/Selection_setBaseAndExtent.html @@ -4,6 +4,7 @@ +
Spacer to check whether or not page was scrolled down to focused editor

static text

content of editor

after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is the "); test(function() { @@ -118,42 +127,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is 'editor'"); test(function() { @@ -161,42 +177,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is 'outerEditor'"); test(function() { @@ -204,42 +227,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is the and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is the and selection is in 'staticInEditor'"); test(function() { @@ -247,42 +277,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is 'innerEditor'"); test(function() { @@ -290,42 +327,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, 0); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, 0); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, 0); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'staticAfter' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, 0); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with collapsed range at start of the first text node of 'anchor' when active element is 'anchor'"); // Selection.setBaseAndExtent() with non-collapsed range in a node. @@ -334,42 +378,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is the "); test(function() { @@ -377,42 +428,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is 'editor'"); test(function() { @@ -420,42 +478,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is 'outerEditor'"); test(function() { @@ -463,42 +528,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { resetFocusAndSelectionRange(staticInEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is 'outerEditor' and selection is in 'staticInEditor'"); test(function() { @@ -506,42 +578,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is 'innerEditor'"); test(function() { @@ -549,42 +628,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, staticBefore.textNode, staticBefore.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in the first text node of 'staticBefore' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(editor.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'editor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'outerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticInEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range in start of the first text node of 'innerEditor' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(staticAfter.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'staticAfter' when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(anchor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range in start of the first text node of 'anchor' when active element is 'anchor'"); // Selection.setBaseAndExtent() with a range across editing host boundary. @@ -593,42 +679,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(editor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is the "); test(function() { resetFocusAndSelectionRange(); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, document.body); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be the after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is the "); test(function() { @@ -636,42 +729,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(editor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'editor'"); test(function() { resetFocusAndSelectionRange(editor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, editor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'editor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'editor'"); test(function() { @@ -679,42 +779,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'outerEditor'"); test(function() { resetFocusAndSelectionRange(outerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'outerEditor'"); test(function() { @@ -722,42 +829,49 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(editor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'innerEditor'"); test(function() { resetFocusAndSelectionRange(innerEditor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, innerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'innerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'innerEditor'"); test(function() { @@ -765,41 +879,48 @@ test(function() { document.getSelection().setBaseAndExtent(staticBefore.textNode, 0, editor.textNode, editor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticBefore' and end of the first text node of 'editor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(editor.textNode, 0, outerEditor.textNode, outerEditor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'editor' and end of the first text node of 'outerEditor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, staticInEditor.textNode, staticInEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'staticInEditor' (common editing host is outerEditor) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(staticInEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'staticInEditor' and end of the first text node of 'innerEditor' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(outerEditor.textNode, 0, innerEditor.textNode, innerEditor.textLength); assert_equals(document.activeElement, outerEditor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'outerEditor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'outerEditor' and end of the first text node of 'innerEditor' (common editing host is outerEditor) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, staticAfter.textNode, staticAfter.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'staticAfter' (no common editing host) when active element is 'anchor'"); test(function() { resetFocusAndSelectionRange(anchor); document.getSelection().setBaseAndExtent(innerEditor.textNode, 0, anchor.textNode, anchor.textLength); assert_equals(document.activeElement, anchor.element); + assert_equals(document.documentElement.scrollTop, 0); }, "Active element should be 'anchor' after Selection.setBaseAndExtent() with a range between start of the first text node of 'innerEditor' and end of the first text node of 'anchor' (no common editing host) when active element is 'anchor'"); diff --git a/testing/web-platform/tests/css/css-scroll-snap/overflowing-snap-areas.html b/testing/web-platform/tests/css/css-scroll-snap/overflowing-snap-areas.html index 6d3c1865fe7b..8f6698d02064 100644 --- a/testing/web-platform/tests/css/css-scroll-snap/overflowing-snap-areas.html +++ b/testing/web-platform/tests/css/css-scroll-snap/overflowing-snap-areas.html @@ -42,7 +42,7 @@ div { }
-
+
@@ -150,4 +150,4 @@ test(() => { }, "Snap to current scroll position on x as the area is covering x axis." + "However, we snap to the specified snap position on y as the area is not " + "covering y axis."); - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html b/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html index ea1442f6706f..9f9da8f648bf 100644 --- a/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html @@ -38,7 +38,7 @@ var height = scroller.clientHeight; [ ["horizontal-tb", 300, 500 - height], ["vertical-lr", 500 - width, 300], - ["vertical-rl", 300, 300] + ["vertical-rl", width - 700, 300] ].forEach(([writing_mode, left, top]) => { test(() => { scroller.style.writingMode = writing_mode; @@ -50,4 +50,4 @@ var height = scroller.clientHeight; }, "Snaps correctly for " + writing_mode + " writing mode with 'inline' and 'block' alignments"); }) - \ No newline at end of file + diff --git a/toolkit/components/clearsitedata/ClearSiteData.cpp b/toolkit/components/clearsitedata/ClearSiteData.cpp index a9409aa7175c..faf57d6d0538 100644 --- a/toolkit/components/clearsitedata/ClearSiteData.cpp +++ b/toolkit/components/clearsitedata/ClearSiteData.cpp @@ -179,17 +179,6 @@ void ClearSiteData::ClearDataFromChannel(nsIHttpChannel* aChannel) { nsresult rv; nsCOMPtr uri; - uint32_t status; - rv = aChannel->GetResponseStatus(&status); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - // We just care about 2xx response status. - if (status < 200 || status >= 300) { - return; - } - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); if (NS_WARN_IF(!ssm)) { return; @@ -258,9 +247,18 @@ void ClearSiteData::ClearDataFromChannel(nsIHttpChannel* aChannel) { } } + // We consider eExecutionContexts only for 2xx response status. if (flags & eExecutionContexts) { - LogOpToConsole(aChannel, uri, eExecutionContexts); - BrowsingContextsReload(holder, principal); + uint32_t status; + rv = aChannel->GetResponseStatus(&status); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + if (status >= 200 && status < 300) { + LogOpToConsole(aChannel, uri, eExecutionContexts); + BrowsingContextsReload(holder, principal); + } } } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 782819e658a4..f3f3b276d063 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10620,16 +10620,6 @@ "releaseChannelCollection": "opt-out", "description": "How often are secure cookies set from non-secure origins, and vice-versa? 0=nonsecure/http, 1=nonsecure/https, 2=secure/http, 3=secure/https" }, - "COOKIE_LEAVE_SECURE_ALONE": { - "record_in_processes": ["main", "content"], - "alert_emails": ["seceng-telemetry@mozilla.com"], - "bug_numbers": [976073, 1325909], - "expires_in_version": "60", - "kind": "enumerated", - "n_values": 10, - "releaseChannelCollection": "opt-out", - "description": "Strict Secure Cookies: 0=blocked secure cookie from http; 1=blocked shadowing secure cookie from http; 2=shadowing secure cookie from https; 3=evicted newer insecure cookie; 4=evicted oldest insecure cookie; 5=evicted secure cookie; 6=evicting secure cookie blocked; 7=blocked downgrading secure cookie from http; 8=downgraded secure cookie from https" - }, "COOKIE_SCHEME_HTTPS": { "record_in_processes": ["main", "content"], "alert_emails": ["cpeterson@mozilla.com", "seceng-telemetry@mozilla.com"], diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm index a86bb2b5812f..9586add9f880 100644 --- a/toolkit/mozapps/extensions/AddonManager.jsm +++ b/toolkit/mozapps/extensions/AddonManager.jsm @@ -1286,6 +1286,11 @@ var AddonManagerInternal = { for (let addon of allAddons) { // Check all add-ons for updates so that any compatibility updates will // be applied + + if (!(addon.permissions & AddonManager.PERM_CAN_UPGRADE)) { + continue; + } + updates.push(new Promise((resolve, reject) => { addon.findUpdates({ onUpdateAvailable(aAddon, aInstall) { diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.jsm b/toolkit/mozapps/extensions/internal/XPIInstall.jsm index 9c9b5a05a5c2..1200b9832d4b 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm +++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm @@ -3002,8 +3002,9 @@ class SystemAddonInstaller extends DirectoryInstaller { let addonSet = SystemAddonInstaller._loadAddonSet(); // Remove any add-ons that are no longer part of the set. + const ids = aAddons.map(a => a.id); for (let addonID of Object.keys(addonSet.addons)) { - if (!aAddons.includes(addonID)) { + if (!ids.includes(addonID)) { AddonManager.getAddonByID(addonID).then(a => a.uninstall()); } } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js new file mode 100644 index 000000000000..2dad1cda4199 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js @@ -0,0 +1,49 @@ +// Tests that system add-on doesnt uninstall while update. + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2"); + +let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"], true); +registerDirectory("XREAppFeat", distroDir); + +AddonTestUtils.usePrivilegedSignatures = "system"; + +add_task(() => initSystemAddonDirs()); + +const initialSetup = { + async setup() { + await buildPrefilledUpdatesDir(); + distroDir.leafName = "empty"; + }, + initialState: [ + { isUpgrade: false, version: null}, + { isUpgrade: true, version: "2.0"}, + ], +}; + +add_task(async function test_systems_update_uninstall_check() { + Services.prefs.setBoolPref(PREF_SYSTEM_ADDON_UPDATE_ENABLED, true); + + await setupSystemAddonConditions(initialSetup, distroDir); + + let updateXML = buildSystemAddonUpdates([ + { id: "system2@tests.mozilla.org", version: "3.0", path: "system2_3.xpi", + xpi: await getSystemAddonXPI(2, "3.0") }, + ]); + + const listener = (msg, {method, params, reason}) => { + if (params.id === "system2@tests.mozilla.org" && method === "uninstall") { + Assert.ok(false, "Should not see uninstall call for system2@tests.mozilla.org"); + } + }; + + AddonTestUtils.on("bootstrap-method", listener); + + await Promise.all([ + updateAllSystemAddons(updateXML), + promiseWebExtensionStartup("system2@tests.mozilla.org"), + ]); + + AddonTestUtils.off("bootstrap-method", listener); + + await promiseShutdownManager(); +}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js new file mode 100644 index 000000000000..e043e041a136 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js @@ -0,0 +1,38 @@ +// Tests that system add-on doesnt request update while normal backgroundUpdateCheck + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2"); + +let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"], true); +registerDirectory("XREAppFeat", distroDir); + +AddonTestUtils.usePrivilegedSignatures = "system"; + +add_task(() => initSystemAddonDirs()); + +const initialSetup = { + async setup() { + await buildPrefilledUpdatesDir(); + distroDir.leafName = "empty"; + }, + initialState: [ + { isUpgrade: false, version: null}, + { isUpgrade: true, version: "2.0"}, + ], +}; + +add_task(async function test_systems_update_uninstall_check() { + await setupSystemAddonConditions(initialSetup, distroDir); + + const testserver = createHttpServer({hosts: ["example.com"]}); + testserver.registerPathHandler("/update.json", (request, response) => { + Assert.ok(!request._queryString.includes("system2@tests.mozilla.org"), + "System addon should not request update from normal update process"); + }); + + Services.prefs.setCharPref("extensions.update.background.url", + "http://example.com/update.json?id=%ITEM_ID%"); + + await AddonManagerInternal.backgroundUpdateCheck(); + + await promiseShutdownManager(); +}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini index 81a50263247c..4d6e3e45a79c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini @@ -223,6 +223,8 @@ skip-if = true # Bug 1501879 head = head_addons.js head_system_addons.js [test_system_update_overlapping.js] head = head_addons.js head_system_addons.js +[test_system_update_uninstall_check.js] +head = head_addons.js head_system_addons.js [test_system_update_upgrades.js] head = head_addons.js head_system_addons.js [test_temporary.js] @@ -244,6 +246,8 @@ skip-if = os == "android" head = head_addons.js head_compat.js [test_update_ignorecompat.js] skip-if = true # Bug 676922 Bug 1437697 +[test_update_noSystemAddonUpdate.js] +head = head_addons.js head_system_addons.js [test_update_strictcompat.js] head = head_addons.js head_compat.js [test_update_webextensions.js] diff --git a/toolkit/mozapps/update/tests/browser/browser.ini b/toolkit/mozapps/update/tests/browser/browser.ini index 65cddf18e9dd..e505fef2f6cc 100644 --- a/toolkit/mozapps/update/tests/browser/browser.ini +++ b/toolkit/mozapps/update/tests/browser/browser.ini @@ -11,8 +11,6 @@ support-files = # About Dialog Application Update Tests [browser_aboutDialog_bc_downloaded.js] [browser_aboutDialog_bc_downloaded_staged.js] -skip-if = (os == "linux" && verify) -reason = Bug 1520672 [browser_aboutDialog_fc_check_cantApply.js] skip-if = os != 'win' reason = test must be able to prevent file deletion. @@ -34,8 +32,6 @@ reason = Windows only feature. # about:preferences Application Update Tests [browser_aboutPrefs_bc_downloaded.js] [browser_aboutPrefs_bc_downloaded_staged.js] -skip-if = (os == "linux" && verify) -reason = Bug 1520672 [browser_aboutPrefs_fc_check_cantApply.js] skip-if = os != 'win' reason = test must be able to prevent file deletion. @@ -64,15 +60,11 @@ reason = test must be able to prevent file deletion. [browser_doorhanger_bc_check_malformedXML.js] [browser_doorhanger_bc_downloaded.js] [browser_doorhanger_bc_downloaded_staged.js] -skip-if = (os == "linux" && verify) -reason = Bug 1520672 [browser_doorhanger_bc_downloadAutoFailures.js] [browser_doorhanger_bc_downloadAutoFailures_bgWin.js] [browser_doorhanger_bc_downloadOptIn.js] [browser_doorhanger_bc_downloadOptIn_bgWin.js] [browser_doorhanger_bc_downloadOptIn_staging.js] -skip-if = (os == "linux" && verify) -reason = Bug 1520672 [browser_doorhanger_bc_patch_completeBadSize.js] [browser_doorhanger_bc_patch_partialBadSize.js] [browser_doorhanger_bc_patch_partialBadSize_complete.js] @@ -81,7 +73,5 @@ reason = Bug 1520672 [browser_doorhanger_sp_patch_partialApplyFailure.js] [browser_doorhanger_sp_patch_partialApplyFailure_complete.js] [browser_doorhanger_sp_patch_partialApplyFailure_complete_staging.js] -skip-if = (os == "linux" && verify) -reason = Bug 1520672 [browser_doorhanger_sp_patch_partialApplyFailure_completeBadSize.js] [browser_TelemetryUpdatePing.js] diff --git a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js index a7a6572631dd..b5757ea25372 100644 --- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js +++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js @@ -1628,7 +1628,7 @@ function copyTestUpdaterToBinDir() { * @return nsIFIle for the copied test updater. */ function copyTestUpdaterForRunUsingUpdater() { - if (AppConstants.platform == "win") { + if (AppConstants.platform == "win" || AppConstants.platform == "linux") { return copyTestUpdaterToBinDir(); } @@ -1639,11 +1639,9 @@ function copyTestUpdaterForRunUsingUpdater() { testUpdater.copyToFollowingLinks(updater.parent, updater.leafName); } - if (AppConstants.platform == "macosx") { - updater.append("Contents"); - updater.append("MacOS"); - updater.append("org.mozilla.updater"); - } + updater.append("Contents"); + updater.append("MacOS"); + updater.append("org.mozilla.updater"); return updater; } @@ -2190,9 +2188,12 @@ function setupAppFiles() { {relPath: "dependentlibs.list", inGreDir: true}]; - // On Linux the updater.png must also be copied + // On Linux the updater.png must also be copied and libsoftokn3.so must be + // symlinked or copied. if (AppConstants.platform == "linux") { appFiles.push({relPath: "icons/updater.png", + inGreDir: true}, + {relPath: "libsoftokn3.so", inGreDir: true}); } @@ -4143,42 +4144,33 @@ function setEnvironment() { gEnv.set("XRE_NO_WINDOWS_CRASH_DIALOG", "1"); } - if (AppConstants.platform == "macosx" || AppConstants.platform == "linux") { + if (AppConstants.platform == "macosx") { + let shouldSetEnv = true; let appGreBinDir = gGREBinDirOrig.clone(); let envGreBinDir = Cc["@mozilla.org/file/local;1"]. createInstance(Ci.nsIFile); - let shouldSetEnv = true; - if (AppConstants.platform == "macosx") { - if (gEnv.exists("DYLD_LIBRARY_PATH")) { - gEnvDyldLibraryPath = gEnv.get("DYLD_LIBRARY_PATH"); - envGreBinDir.initWithPath(gEnvDyldLibraryPath); - if (envGreBinDir.path == appGreBinDir.path) { - gEnvDyldLibraryPath = null; - shouldSetEnv = false; - } - } - - if (shouldSetEnv) { - debugDump("setting DYLD_LIBRARY_PATH environment variable value to " + - appGreBinDir.path); - gEnv.set("DYLD_LIBRARY_PATH", appGreBinDir.path); - } - } else { - if (gEnv.exists("LD_LIBRARY_PATH")) { - gEnvLdLibraryPath = gEnv.get("LD_LIBRARY_PATH"); - envGreBinDir.initWithPath(gEnvLdLibraryPath); - if (envGreBinDir.path == appGreBinDir.path) { - gEnvLdLibraryPath = null; - shouldSetEnv = false; - } - } - - if (shouldSetEnv) { - debugDump("setting LD_LIBRARY_PATH environment variable value to " + - appGreBinDir.path); - gEnv.set("LD_LIBRARY_PATH", appGreBinDir.path); + if (gEnv.exists("DYLD_LIBRARY_PATH")) { + gEnvDyldLibraryPath = gEnv.get("DYLD_LIBRARY_PATH"); + envGreBinDir.initWithPath(gEnvDyldLibraryPath); + if (envGreBinDir.path == appGreBinDir.path) { + gEnvDyldLibraryPath = null; + shouldSetEnv = false; } } + + if (shouldSetEnv) { + debugDump("setting DYLD_LIBRARY_PATH environment variable value to " + + appGreBinDir.path); + gEnv.set("DYLD_LIBRARY_PATH", appGreBinDir.path); + } + } + + if (AppConstants.platform == "linux" && gEnv.exists("LD_LIBRARY_PATH")) { + gEnvLdLibraryPath = gEnv.get("LD_LIBRARY_PATH"); + debugDump("removing LD_LIBRARY_PATH environment variable"); + // By removing the LD_LIBRARY_PATH environment variable this will test + // that setting the rpath for the updater is working properly. + gEnv.set("LD_LIBRARY_PATH", ""); } if (gEnv.exists("XPCOM_MEM_LEAK_LOG")) { @@ -4232,26 +4224,23 @@ function resetEnvironment() { gEnv.set("XPCOM_DEBUG_BREAK", ""); } - if (AppConstants.platform == "macosx" || AppConstants.platform == "linux") { - if (AppConstants.platform == "macosx") { - if (gEnvDyldLibraryPath) { - debugDump("setting DYLD_LIBRARY_PATH environment variable value " + - "back to " + gEnvDyldLibraryPath); - gEnv.set("DYLD_LIBRARY_PATH", gEnvDyldLibraryPath); - } else if (gEnvDyldLibraryPath !== null) { - debugDump("removing DYLD_LIBRARY_PATH environment variable"); - gEnv.set("DYLD_LIBRARY_PATH", ""); - } - } else if (gEnvLdLibraryPath) { - debugDump("setting LD_LIBRARY_PATH environment variable value back " + - "to " + gEnvLdLibraryPath); - gEnv.set("LD_LIBRARY_PATH", gEnvLdLibraryPath); - } else if (gEnvLdLibraryPath !== null) { - debugDump("removing LD_LIBRARY_PATH environment variable"); - gEnv.set("LD_LIBRARY_PATH", ""); + if (AppConstants.platform == "macosx") { + if (gEnvDyldLibraryPath) { + debugDump("setting DYLD_LIBRARY_PATH environment variable value " + + "back to " + gEnvDyldLibraryPath); + gEnv.set("DYLD_LIBRARY_PATH", gEnvDyldLibraryPath); + } else if (gEnvDyldLibraryPath !== null) { + debugDump("removing DYLD_LIBRARY_PATH environment variable"); + gEnv.set("DYLD_LIBRARY_PATH", ""); } } + if (AppConstants.platform == "linux" && gEnvLdLibraryPath) { + debugDump("setting LD_LIBRARY_PATH environment variable value back " + + "to " + gEnvLdLibraryPath); + gEnv.set("LD_LIBRARY_PATH", gEnvLdLibraryPath); + } + if (AppConstants.platform == "win" && gAddedEnvXRENoWindowsCrashDialog) { debugDump("removing the XRE_NO_WINDOWS_CRASH_DIALOG environment " + "variable"); diff --git a/toolkit/mozapps/update/updater/progressui_gtk.cpp b/toolkit/mozapps/update/updater/progressui_gtk.cpp index e83630f86c01..d64ff94c1d3f 100644 --- a/toolkit/mozapps/update/updater/progressui_gtk.cpp +++ b/toolkit/mozapps/update/updater/progressui_gtk.cpp @@ -22,8 +22,9 @@ static guint sTimerID; static GtkWidget *sWin; static GtkWidget *sLabel; static GtkWidget *sProgressBar; +static GdkPixbuf *sPixbuf; -static const char *sProgramPath; +StringTable sStrings; static gboolean UpdateDialog(gpointer data) { if (sQuit) { @@ -45,9 +46,20 @@ static gboolean OnDeleteEvent(GtkWidget *widget, GdkEvent *event, } int InitProgressUI(int *pargc, char ***pargv) { - sProgramPath = (*pargv)[0]; - sEnableUI = gtk_init_check(pargc, pargv); + if (sEnableUI) { + // Prepare to show the UI here in case the files are modified by the update. + char ini_path[PATH_MAX]; + SprintfLiteral(ini_path, "%s.ini", (*pargv)[0]); + if (ReadStrings(ini_path, &sStrings) != OK) { + sEnableUI = false; + return -1; + } + + char icon_path[PATH_MAX]; + SprintfLiteral(icon_path, "%s/icons/updater.png", (*pargv)[2]); + sPixbuf = gdk_pixbuf_new_from_file(icon_path, nullptr); + } return 0; } @@ -65,38 +77,25 @@ int ShowProgressUI() { return 0; } - char ini_path[PATH_MAX]; - SprintfLiteral(ini_path, "%s.ini", sProgramPath); - - StringTable strings; - if (ReadStrings(ini_path, &strings) != OK) { - return -1; - } - sWin = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (!sWin) { return -1; } - static GdkPixbuf *pixbuf; - char icon_path[PATH_MAX]; - SprintfLiteral(icon_path, "%s.png", sProgramPath); - g_signal_connect(G_OBJECT(sWin), "delete_event", G_CALLBACK(OnDeleteEvent), nullptr); - gtk_window_set_title(GTK_WINDOW(sWin), strings.title); + gtk_window_set_title(GTK_WINDOW(sWin), sStrings.title); gtk_window_set_type_hint(GTK_WINDOW(sWin), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_position(GTK_WINDOW(sWin), GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_resizable(GTK_WINDOW(sWin), FALSE); gtk_window_set_decorated(GTK_WINDOW(sWin), TRUE); gtk_window_set_deletable(GTK_WINDOW(sWin), FALSE); - pixbuf = gdk_pixbuf_new_from_file(icon_path, nullptr); - gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf); - g_object_unref(pixbuf); + gtk_window_set_icon(GTK_WINDOW(sWin), sPixbuf); + g_object_unref(sPixbuf); GtkWidget *vbox = gtk_vbox_new(TRUE, 6); - sLabel = gtk_label_new(strings.info); + sLabel = gtk_label_new(sStrings.info); gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f); sProgressBar = gtk_progress_bar_new(); diff --git a/toolkit/mozapps/update/updater/updater-common.build b/toolkit/mozapps/update/updater/updater-common.build index a6b9259fe931..17f4050a7c8c 100644 --- a/toolkit/mozapps/update/updater/updater-common.build +++ b/toolkit/mozapps/update/updater/updater-common.build @@ -45,6 +45,7 @@ elif CONFIG['OS_ARCH'] == 'Linux' and CONFIG['MOZ_VERIFY_MAR_SIGNATURE']: 'signmar', ] OS_LIBS += CONFIG['NSPR_LIBS'] + LDFLAGS += ['-Wl,-rpath=$ORIGIN'] USE_LIBS += [ 'bspatch', diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 4d3a96687855..151010233c16 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -2683,7 +2683,7 @@ int NS_main(int argc, NS_tchar **argv) { // need to initialize NSS at all there. // Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS // databases. - if (NSS_NoDB_Init(NULL) != SECSuccess) { + if (NSS_NoDB_Init(nullptr) != SECSuccess) { PRErrorCode error = PR_GetError(); fprintf(stderr, "Could not initialize NSS: %s (%d)", PR_ErrorToName(error), (int)error); diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp index 8d089ed028a4..d784aae35686 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -66,13 +66,11 @@ static LazyLogModule sUpdateLog("updatedriver"); #else # define UPDATER_BIN "updater" #endif -#define UPDATER_INI "updater.ini" +// On Mac OS X these files are copied into the update directory. #ifdef XP_MACOSX +# define UPDATER_INI "updater.ini" # define UPDATER_APP "updater.app" #endif -#if defined(XP_UNIX) && !defined(XP_MACOSX) -# define UPDATER_PNG "updater.png" -#endif #ifdef XP_MACOSX static void UpdateDriverSetupMacCommandLine(int &argc, char **&argv, @@ -286,7 +284,7 @@ static bool IsOlderVersion(nsIFile *versionFile, const char *appVersion) { return false; } -#if !defined(XP_WIN) +#if defined(XP_MACOSX) static bool CopyFileIntoUpdateDir(nsIFile *parentDir, const nsACString &leaf, nsIFile *updateDir) { nsCOMPtr file; @@ -313,29 +311,13 @@ static bool CopyUpdaterIntoUpdateDir(nsIFile *greDir, nsIFile *appDir, nsIFile *updateDir, nsCOMPtr &updater) { // Copy the updater application from the GRE and the updater ini from the app. -# if defined(XP_MACOSX) if (!CopyFileIntoUpdateDir(appDir, NS_LITERAL_CSTRING(UPDATER_APP), updateDir)) return false; CopyFileIntoUpdateDir(greDir, NS_LITERAL_CSTRING(UPDATER_INI), updateDir); -# else - if (!CopyFileIntoUpdateDir(greDir, NS_LITERAL_CSTRING(UPDATER_BIN), - updateDir)) - return false; - CopyFileIntoUpdateDir(appDir, NS_LITERAL_CSTRING(UPDATER_INI), updateDir); -# endif -# if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(ANDROID) - nsCOMPtr iconDir; - appDir->Clone(getter_AddRefs(iconDir)); - iconDir->AppendNative(NS_LITERAL_CSTRING("icons")); - if (!CopyFileIntoUpdateDir(iconDir, NS_LITERAL_CSTRING(UPDATER_PNG), - updateDir)) - return false; -# endif // Finally, return the location of the updater binary. nsresult rv = updateDir->Clone(getter_AddRefs(updater)); if (NS_FAILED(rv)) return false; -# if defined(XP_MACOSX) rv = updater->AppendNative(NS_LITERAL_CSTRING(UPDATER_APP)); nsresult tmp = updater->AppendNative(NS_LITERAL_CSTRING("Contents")); if (NS_FAILED(tmp)) { @@ -343,39 +325,11 @@ static bool CopyUpdaterIntoUpdateDir(nsIFile *greDir, nsIFile *appDir, } tmp = updater->AppendNative(NS_LITERAL_CSTRING("MacOS")); if (NS_FAILED(tmp) || NS_FAILED(rv)) return false; -# endif rv = updater->AppendNative(NS_LITERAL_CSTRING(UPDATER_BIN)); return NS_SUCCEEDED(rv); } #endif -/** - * Appends the specified path to the library path. - * This is used so that updater can find libmozsqlite3.so and other shared libs. - * - * @param pathToAppend A new library path to prepend to LD_LIBRARY_PATH - */ -#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX) -# include "prprf.h" -# define PATH_SEPARATOR ":" -# define LD_LIBRARY_PATH_ENVVAR_NAME "LD_LIBRARY_PATH" -static void AppendToLibPath(const char *pathToAppend) { - char *pathValue = getenv(LD_LIBRARY_PATH_ENVVAR_NAME); - if (nullptr == pathValue || '\0' == *pathValue) { - // Leak the string because that is required by PR_SetEnv. - char *s = - Smprintf("%s=%s", LD_LIBRARY_PATH_ENVVAR_NAME, pathToAppend).release(); - PR_SetEnv(s); - } else if (!strstr(pathValue, pathToAppend)) { - // Leak the string because that is required by PR_SetEnv. - char *s = Smprintf("%s=%s" PATH_SEPARATOR "%s", LD_LIBRARY_PATH_ENVVAR_NAME, - pathToAppend, pathValue) - .release(); - PR_SetEnv(s); - } -} -#endif - /** * Applies, switches, or stages an update. * @@ -426,7 +380,7 @@ static void ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *appDir, return; } updateDirPath = NS_ConvertUTF16toUTF8(updateDirPathW); -#else +#elif defined(XP_MACOSX) if (isStaged) { nsCOMPtr mozUpdaterDir; rv = updateDir->Clone(getter_AddRefs(mozUpdaterDir)); @@ -472,6 +426,23 @@ static void ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *appDir, return; } + // Get the path to the update dir. + rv = updateDir->GetNativePath(updateDirPath); + if (NS_FAILED(rv)) { + return; + } +#else + // Get an nsIFile reference for the updater in the installation dir. + if (!GetFile(greDir, NS_LITERAL_CSTRING(UPDATER_BIN), updater)) { + return; + } + + // Get the path to the updater that will be used. + rv = updater->GetNativePath(updaterPath); + if (NS_FAILED(rv)) { + return; + } + // Get the path to the update dir. rv = updateDir->GetNativePath(updateDirPath); if (NS_FAILED(rv)) { @@ -622,10 +593,6 @@ static void ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *appDir, PR_SetEnv("MOZ_SAFE_MODE_RESTART=1"); } -#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX) - AppendToLibPath(installDirPath.get()); -#endif - LOG(("spawning updater process [%s]\n", updaterPath.get())); #if defined(XP_UNIX) && !defined(XP_MACOSX)