Compare commits

...
13 Commits
Author SHA1 Message Date
Moonchild 44d17e4ee7 Replace strnlen with memchr. See code comment. 2026-08-15 10:19:41 +02:00
Moonchild 26cc7c3126 Revert "Refactor string utils in MFBT."
This reverts commit cea1b66ba5.
2026-08-15 09:49:46 +02:00
Moonchild cea1b66ba5 Refactor string utils in MFBT.
This adds an Apple carveout for strnlen for OS X < 10.7 and renames the
ToString.h header to StringUtils.h to better reflect the more generic
collection of functions in it, instead of a 1-file-1-method header.
2026-08-13 16:42:35 +02:00
Moonchild 948559c22c Revert "[parser] Restrict subtree root check to DOM image elements only."
As it turns out, the reported regression was actually noncompliant HTML
and the initial implementation was correct.

This reverts commit fc25f50e5f.
2026-08-11 17:39:55 +02:00
Moonchild 5d7a1ca5a9 Merge pull request 'Several Python 3-related fixes to the build system' (#3160) from FranklinDM/UXP-contrib:work_python3-fixes-build1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3160
2026-08-10 12:40:05 +00:00
Francis Dominic Fajardo 613443c5eb No issue - Remove old Python 2 workaround that encodes environment vars in bytes
This should fix installer packaging.
2026-08-10 19:10:18 +08:00
Basilisk-Dev d7884bb96c No issue - Fix faster build packaging on Python 3 2026-08-10 19:10:11 +08:00
Moonchild fc25f50e5f [parser] Restrict subtree root check to DOM image elements only.
This was too broadly applied, resulting in named form elements not being
accessible through the DOM tree if not in the same subtree root.
2026-08-09 18:50:50 +02:00
Moonchild b70b3a5aa1 Merge pull request 'Clean up NSIS scripting.' (#3121) from nsis-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3121
2026-08-06 13:50:39 +00:00
Moonchild 88ae39ed04 Merge pull request 'Implement :has() CSS pseudo class' (#3152) from Basilisk-Dev/UXP-contrib:css-has into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3152
2026-08-06 06:34:14 +00:00
Basilisk-Dev d893526f82 Issue #2473 - Inline functions in CSS :has() implementation 2026-07-29 16:48:12 -04:00
Basilisk-Dev 7341809f67 Issue #2473 - implement :has() CSS pseudo class 2026-07-26 14:35:40 -04:00
Moonchild 21743e0b7c Issue #3120 - Clean up NSIS scripting.
Removes Quicklaunch shortcut code, UAC guards (always supported on target
OSes) and LSP guards (ditto).

Resolves #3120
2026-06-13 12:19:53 +02:00
19 changed files with 668 additions and 315 deletions

No files matched your search

+1 -1
View File
@@ -81,7 +81,7 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/
--track install_$(subst /,_,$*).track \
$(TOPOBJDIR)/$* \
-DAB_CD=en-US \
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/$(MOZ_BUILD_APP)/locales/en-US/profile \
$(ACDEFINES) \
install_$(subst /,_,$*)
+1
View File
@@ -444,6 +444,7 @@ GK_ATOM(handheldFriendly, "HandheldFriendly")
GK_ATOM(handler, "handler")
GK_ATOM(handlers, "handlers")
GK_ATOM(HARD, "HARD")
GK_ATOM(hasSelectorDependency, "has-selector-dependency")
GK_ATOM(hasSameNode, "has-same-node")
GK_ATOM(hbox, "hbox")
GK_ATOM(head, "head")
+7 -1
View File
@@ -312,7 +312,13 @@ cvt_s(SprintfState* ss, const char* s, int width, int prec, int flags)
s = generic_null_str(s);
// Limit string length by precision value
size_t slen = strnlen(s, size_t(prec));
// We'd want to use strnlen() here, but it is not supported by all targets
// (Most notably old OS X), so use memchr instead.
// Replace with `size_t slen = strnlen(s, size_t(prec));` once we no longer
// need to cater to this.
const char* sptr = (const char*)memchr(s, 0, size_t(prec));
size_t slen = sptr ? sptr - s : size_t(prec);
if (slen > INT_MAX) {
return false;
}
+38
View File
@@ -13,6 +13,7 @@
#include <algorithm> // For std::max
#include "mozilla/EffectSet.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/ShadowRoot.h"
#include "nsLayoutUtils.h"
#include "AnimationCommon.h" // For GetLayerAnimationInfo
#include "FrameLayerBuilder.h"
@@ -260,6 +261,7 @@ RestyleManager::ContentStateChanged(nsIContent* aContent,
ContentStateChangedInternal(aElement, aStateMask, &changeHint, &restyleHint);
PostRestyleEvent(aElement, restyleHint, changeHint);
RestyleForHasPseudoClassChange(aElement);
}
// Forwarded nsIMutationObserver method, to handle restyling.
@@ -371,6 +373,30 @@ RestyleManager::AttributeChanged(Element* aElement,
aOldValue,
rsdata);
PostRestyleEvent(aElement, rshint, hint, &rsdata);
RestyleForHasPseudoClassChange(aElement);
}
bool
RestyleManager::RestyleForHasPseudoClassChange(nsINode* aNode)
{
Element* affectedRoot = nullptr;
for (nsINode* node = aNode; node; node = node->GetParentNode()) {
if (!node->GetProperty(nsGkAtoms::hasSelectorDependency)) {
continue;
}
if (node->IsElement()) {
affectedRoot = node->AsElement();
} else if (ShadowRoot* shadow = ShadowRoot::FromNode(node)) {
affectedRoot = shadow->GetHost();
}
}
if (!affectedRoot) {
return false;
}
PostRestyleEvent(affectedRoot, eRestyle_Subtree, nsChangeHint(0));
return true;
}
/* static */ uint64_t
@@ -399,6 +425,10 @@ RestyleManager::RestyleForAppend(nsIContent* aContainer,
nsIContent* aFirstNewContent)
{
// The container cannot be a document, but might be a ShadowRoot.
if (RestyleForHasPseudoClassChange(aContainer)) {
return;
}
if (!aContainer->IsElement()) {
return;
}
@@ -488,6 +518,10 @@ RestyleManager::RestyleForInsertOrChange(nsINode* aContainer,
nsIContent* aChild)
{
// The container might be a document or a ShadowRoot.
if (RestyleForHasPseudoClassChange(aContainer)) {
return;
}
if (!aContainer->IsElement()) {
return;
}
@@ -578,6 +612,10 @@ RestyleManager::ContentRemoved(nsINode* aContainer,
nsIContent* aFollowingSibling)
{
// The container might be a document or a ShadowRoot.
if (RestyleForHasPseudoClassChange(aContainer)) {
return;
}
if (!aContainer->IsElement()) {
return;
}
+4
View File
@@ -314,6 +314,10 @@ public:
// the container is null, no work is needed.
void RestyleForAppend(nsIContent* aContainer, nsIContent* aFirstNewContent);
// Restyle a subtree containing any :has() anchor affected by a change at
// or below aNode. Returns true when such a restyle was posted.
bool RestyleForHasPseudoClassChange(nsINode* aNode);
// Process any pending restyles. This should be called after
// CreateNeededFrames.
// Note: It's the caller's responsibility to make sure to wrap a
+30 -2
View File
@@ -993,7 +993,8 @@ nsCSSSelector::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
nsCSSSelectorList::nsCSSSelectorList(void)
: mSelectors(nullptr),
mWeight(0),
mNext(nullptr)
mNext(nullptr),
mIsRelativeSelector(false)
{
MOZ_COUNT_CTOR(nsCSSSelectorList);
}
@@ -1047,7 +1048,33 @@ nsCSSSelectorList::ToString(nsAString& aResult, CSSStyleSheet* aSheet)
return;
}
for (;;) {
p->mSelectors->ToString(aResult, aSheet, true);
if (p->mIsRelativeSelector) {
// :has() arguments are represented internally as selectors with an
// implicit leftmost anchor. Serialize the authored relative selector,
// including an explicit leading combinator when there is one.
const nsCSSSelector* leftmost = p->mSelectors;
while (leftmost->mNext && leftmost->mNext->mNext) {
leftmost = leftmost->mNext;
}
MOZ_ASSERT(leftmost->mNext,
"relative selector should have an implicit anchor");
if (leftmost->mNext->mOperator != char16_t(' ')) {
aResult.Append(leftmost->mNext->mOperator);
aResult.Append(char16_t(' '));
}
nsAutoPtr<nsCSSSelector> selectors(p->mSelectors->Clone());
nsCSSSelector* beforeAnchor = selectors;
while (beforeAnchor->mNext && beforeAnchor->mNext->mNext) {
beforeAnchor = beforeAnchor->mNext;
}
MOZ_ASSERT(beforeAnchor->mNext);
delete beforeAnchor->mNext;
beforeAnchor->mNext = nullptr;
selectors->ToString(aResult, aSheet, true);
} else {
p->mSelectors->ToString(aResult, aSheet, true);
}
p = p->mNext;
if (!p)
break;
@@ -1060,6 +1087,7 @@ nsCSSSelectorList::Clone(bool aDeep) const
{
nsCSSSelectorList *result = new nsCSSSelectorList();
result->mWeight = mWeight;
result->mIsRelativeSelector = mIsRelativeSelector;
NS_IF_CLONE(mSelectors);
if (aDeep) {
+4
View File
@@ -314,6 +314,10 @@ struct nsCSSSelectorList {
nsCSSSelector* mSelectors;
int32_t mWeight;
nsCSSSelectorList* mNext;
// Relative selector lists used by :has() have an implicit internal anchor
// stored as their leftmost selector. This flag keeps that implementation
// detail out of serialization and is preserved by cloning.
bool mIsRelativeSelector;
protected:
friend class inDOMUtils;
nsCSSSelectorList* Clone(bool aDeep) const;
+37 -2
View File
@@ -127,7 +127,9 @@ enum class SelectorParsingFlags {
eDisallowCombinators = 1 << 2,
eDisallowPseudoElements = 1 << 3,
eInheritNamespace = 1 << 4,
eForceEmptyList = 1 << 5
eForceEmptyList = 1 << 5,
eIsRelativeSelector = 1 << 6,
eInsideHas = 1 << 7
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SelectorParsingFlags)
@@ -6452,6 +6454,28 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList,
char16_t combinator = 0;
nsAutoPtr<nsCSSSelectorList> list(new nsCSSSelectorList());
if (aFlags & SelectorParsingFlags::eIsRelativeSelector) {
// A relative selector is evaluated as though it begins with an internal
// anchor and a combinator. This must not use :scope: an explicit :scope
// in the argument continues to refer to the caller's scoping root.
// If the combinator is omitted, it is a descendant combinator.
nsCSSSelector* anchor = list->AddSelector(char16_t(0));
anchor->AddPseudoClass(CSSPseudoClassType::mozHasRelativeAnchor);
list->mIsRelativeSelector = true;
combinator = char16_t(' ');
if (GetToken(true)) {
if (mToken.mType == eCSSToken_Symbol &&
(mToken.mSymbol == '+' ||
mToken.mSymbol == '>' ||
mToken.mSymbol == '~')) {
combinator = mToken.mSymbol;
} else {
UngetToken();
}
}
}
for (;;) {
if (!ParseSelector(list, combinator, aFlags)) {
return false;
@@ -7125,6 +7149,9 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
if (aFlags & SelectorParsingFlags::eDisallowCombinators) {
flags |= SelectorParsingFlags::eDisallowCombinators;
}
if (aFlags & SelectorParsingFlags::eInsideHas) {
flags |= SelectorParsingFlags::eInsideHas;
}
if (aFlags & SelectorParsingFlags::eForceEmptyList ||
forceEmptyList) {
flags |= SelectorParsingFlags::eForceEmptyList;
@@ -7570,7 +7597,15 @@ CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector,
bool isSingleSelector =
nsCSSPseudoClasses::HasSingleSelectorArg(aType);
if (nsCSSPseudoClasses::HasForgivingSelectorListArg(aType)) {
if (aType == CSSPseudoClassType::has) {
// :has() takes an unforgiving <relative-selector-list>, cannot be nested,
// and cannot contain pseudo-elements.
if (aFlags & SelectorParsingFlags::eInsideHas) {
return eSelectorParsingStatus_Error;
}
aFlags |= SelectorParsingFlags::eIsRelativeSelector |
SelectorParsingFlags::eInsideHas;
} else if (nsCSSPseudoClasses::HasForgivingSelectorListArg(aType)) {
aFlags |= SelectorParsingFlags::eIsForgiving;
} else if (isSingleSelector || aType == CSSPseudoClassType::mozAny) {
aFlags |= SelectorParsingFlags::eDisallowCombinators;
+3
View File
@@ -77,6 +77,9 @@ CSS_PSEUDO_CLASS(is, ":is", 0, "layout.css.is-where-pseudo.enabled")
CSS_PSEUDO_CLASS(matches, ":matches", 0, "layout.css.is-where-pseudo.enabled")
CSS_PSEUDO_CLASS(any, ":any", 0, "layout.css.is-where-pseudo.enabled")
CSS_PSEUDO_CLASS(where, ":where", 0, "layout.css.is-where-pseudo.enabled")
CSS_PSEUDO_CLASS(has, ":has", 0, "")
CSS_PSEUDO_CLASS(mozHasRelativeAnchor, ":-moz-has-relative-anchor",
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "")
CSS_PSEUDO_CLASS(firstChild, ":first-child", 0, "")
CSS_PSEUDO_CLASS(firstNode, ":-moz-first-node", 0, "")
+1
View File
@@ -159,6 +159,7 @@ bool
nsCSSPseudoClasses::HasSelectorListArg(Type aType)
{
return HasForgivingSelectorListArg(aType) ||
aType == Type::has ||
aType == Type::negation ||
aType == Type::mozAny ||
aType == Type::mozAnyPrivate ||
+171 -27
View File
@@ -887,20 +887,34 @@ nsCSSRuleUtils::SelectorMatches(Element* aElement,
}
break;
case CSSPseudoClassType::is:
case CSSPseudoClassType::matches:
case CSSPseudoClassType::any:
case CSSPseudoClassType::where: {
case CSSPseudoClassType::is:
case CSSPseudoClassType::matches:
case CSSPseudoClassType::any:
case CSSPseudoClassType::where: {
if (!SelectorListMatches(aElement,
pseudoClass,
aNodeMatchContext,
aTreeMatchContext,
true)) {
return false;
}
} break;
case CSSPseudoClassType::mozAny: {
}
} break;
case CSSPseudoClassType::has: {
if (!RelativeSelectorListMatches(aElement,
pseudoClass->u.mSelectorList,
aTreeMatchContext)) {
return false;
}
} break;
case CSSPseudoClassType::mozHasRelativeAnchor:
if (aElement != aTreeMatchContext.mRelativeSelectorAnchor) {
return false;
}
break;
case CSSPseudoClassType::mozAny: {
// XXX: For compatibility, we retain :-moz-any()'s original behavior,
// which is to be unforgiving and reject complex selectors in
// its selector list argument.
@@ -1626,8 +1640,10 @@ nsCSSRuleUtils::SelectorListMatches(Element* aElement,
SelectorMatchesTreeFlags selectorTreeFlags = SelectorMatchesTreeFlags(0);
// Try to look for the closest ancestor link element if we're processing
// the selector list argument of a pseudo-class, but only if for a new style context (see SelectorMatches).
if (!aNodeMatchContext.mIsRelevantLink && aTreeMatchContext.mForStyling &&
(aSelectorFlags & SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT)) {
if (!aNodeMatchContext.mIsRelevantLink &&
!aTreeMatchContext.mRelativeSelectorAnchor &&
aTreeMatchContext.mForStyling &&
(aSelectorFlags & SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT)) {
selectorTreeFlags = eLookForRelevantLink;
}
@@ -1644,23 +1660,151 @@ nsCSSRuleUtils::SelectorListMatches(Element* aElement,
}
/* static */ bool
nsCSSRuleUtils::SelectorListMatches(Element* aElement,
nsPseudoClassList* aList,
NodeMatchContext& aNodeMatchContext,
TreeMatchContext& aTreeMatchContext,
bool aIsForgiving,
bool aPreventComplexSelectors)
{
return SelectorListMatches(aElement,
aList->u.mSelectorList,
aNodeMatchContext,
aTreeMatchContext,
SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT,
aIsForgiving,
aPreventComplexSelectors);
}
// TreeMatchContext and AncestorFilter out of line methods
nsCSSRuleUtils::SelectorListMatches(Element* aElement,
nsPseudoClassList* aList,
NodeMatchContext& aNodeMatchContext,
TreeMatchContext& aTreeMatchContext,
bool aIsForgiving,
bool aPreventComplexSelectors)
{
return SelectorListMatches(aElement,
aList->u.mSelectorList,
aNodeMatchContext,
aTreeMatchContext,
SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT,
aIsForgiving,
aPreventComplexSelectors);
}
static inline bool
matchesCandidate(Element* aCandidate,
nsCSSSelectorList* aRelativeSelector,
TreeMatchContext& aTreeMatchContext)
{
AutoRestore<Element*> styleScopeRestorer(
aTreeMatchContext.mCurrentStyleScope);
// A candidate inspected by :has() is never the relevant link for the
// anchor being styled. Treating it as relevant would allow
// :has(:visited) to expose link history through an ancestor.
NodeMatchContext nodeContext(EventStates(), false);
nsCSSSelector* selector = aRelativeSelector->mSelectors;
if (!nsCSSRuleUtils::SelectorMatches(
aCandidate,
selector,
nodeContext,
aTreeMatchContext,
SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT)) {
return false;
}
return !selector->mNext ||
nsCSSRuleUtils::SelectorMatchesTree(
aCandidate,
selector->mNext,
aTreeMatchContext,
SelectorMatchesTreeFlags(0));
}
static inline bool
matchesSubtree(nsIContent* aRoot,
nsCSSSelectorList* aRelativeSelector,
TreeMatchContext& aTreeMatchContext)
{
for (nsIContent* node = aRoot;
node;
node = node->GetNextNode(aRoot)) {
if (node->IsElement() &&
matchesCandidate(node->AsElement(),
aRelativeSelector,
aTreeMatchContext)) {
return true;
}
}
return false;
}
/* static */ bool
nsCSSRuleUtils::RelativeSelectorListMatches(
Element* aAnchor,
nsCSSSelectorList* aList,
TreeMatchContext& aTreeMatchContext)
{
MOZ_ASSERT(aAnchor);
MOZ_ASSERT(aList);
// :has() reverses the usual direction of selector invalidation. The
// restyle manager uses these conservative markers to promote changes in the
// anchor's descendants, or in following sibling subtrees, back to a subtree
// that contains the anchor.
if (aTreeMatchContext.mForStyling) {
aAnchor->SetProperty(nsGkAtoms::hasSelectorDependency,
reinterpret_cast<void*>(1));
nsIContent* parent = aAnchor->GetParent();
if (parent) {
parent->SetProperty(nsGkAtoms::hasSelectorDependency,
reinterpret_cast<void*>(1));
}
}
AutoRestore<Element*> relativeAnchorRestorer(
aTreeMatchContext.mRelativeSelectorAnchor);
aTreeMatchContext.mRelativeSelectorAnchor = aAnchor;
for (nsCSSSelectorList* relative = aList;
relative;
relative = relative->mNext) {
MOZ_ASSERT(relative->mIsRelativeSelector);
MOZ_ASSERT(relative->mSelectors && relative->mSelectors->mNext);
// Find the compound immediately to the right of the implicit internal
// anchor. This selector representation stores a combinator on its
// left-hand selector, so the anchor owns the leading combinator.
nsCSSSelector* leftmost = relative->mSelectors;
while (leftmost->mNext && leftmost->mNext->mNext) {
leftmost = leftmost->mNext;
}
MOZ_ASSERT(leftmost->mNext);
switch (leftmost->mNext->mOperator) {
// Even for a leading adjacent-sibling combinator, a later combinator in
// the relative selector can move the rightmost matching element into a
// subsequent sibling subtree (for example, :has(+ .a + .b)). Search
// every following subtree and let the full selector enforce the exact
// leading relationship to the anchor.
case char16_t('+'):
case char16_t('~'):
for (Element* sibling = aAnchor->GetNextElementSibling();
sibling;
sibling = sibling->GetNextElementSibling()) {
if (matchesSubtree(sibling, relative, aTreeMatchContext)) {
return true;
}
}
break;
case char16_t('>'):
case char16_t(' '):
for (nsIContent* node = aAnchor->GetFirstChild();
node;
node = node->GetNextNode(aAnchor)) {
if (node->IsElement() &&
matchesCandidate(node->AsElement(),
relative,
aTreeMatchContext)) {
return true;
}
}
break;
default:
MOZ_ASSERT(false, "unexpected relative selector combinator");
break;
}
}
return false;
}
// TreeMatchContext and AncestorFilter out of line methods
void
TreeMatchContext::InitAncestors(Element* aElement)
{
+12 -7
View File
@@ -69,13 +69,18 @@ struct nsCSSRuleUtils
bool aIsForgiving = false,
bool aPreventComplexSelectors = false);
static bool SelectorListMatches(Element* aElement,
nsPseudoClassList* aList,
NodeMatchContext& aNodeMatchContext,
TreeMatchContext& aTreeMatchContext,
bool aIsForgiving = false,
bool aPreventComplexSelectors = false);
static bool SelectorListMatches(Element* aElement,
nsPseudoClassList* aList,
NodeMatchContext& aNodeMatchContext,
TreeMatchContext& aTreeMatchContext,
bool aIsForgiving = false,
bool aPreventComplexSelectors = false);
static bool RelativeSelectorListMatches(
Element* aAnchor,
nsCSSSelectorList* aList,
TreeMatchContext& aTreeMatchContext);
#ifdef DEBUG
static bool HasPseudoClassSelectorArgsWithCombinators(
nsCSSSelector* aSelector);
+6
View File
@@ -449,6 +449,7 @@ struct MOZ_STACK_CLASS TreeMatchContext {
, mCurrentStyleScope(nullptr)
, mIsTopmostScope(false)
, mForAssignedSlot(false)
, mRelativeSelectorAnchor(nullptr)
{
if (aMatchVisited != eNeverMatchVisited) {
nsILoadContext* loadContext = mDocument->GetLoadContext();
@@ -466,6 +467,11 @@ struct MOZ_STACK_CLASS TreeMatchContext {
nsRuleWalker::eRelevantLinkUnvisited,
aDocument)
{}
// The anchor used by the implementation-only leftmost compound of a
// relative selector. This is deliberately separate from mScopes: an
// explicit :scope inside :has() still refers to the API/style scope.
mozilla::dom::Element* mRelativeSelectorAnchor;
};
struct MOZ_STACK_CLASS RuleProcessorData {
+1
View File
@@ -250,6 +250,7 @@ support-files = redundant_font_download.sjs
[test_rule_insertion.html]
[test_rule_serialization.html]
[test_rules_out_of_sheets.html]
[test_has_pseudo_class.html]
[test_selectors.html]
[test_selectors_on_anonymous_content.html]
[test_setPropertyWithNull.html]
@@ -0,0 +1,167 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS :has() relational pseudo-class</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<style id="has-styles">
.dynamic,
.structural,
.sibling-anchor,
.state-anchor,
.empty-anchor {
color: rgb(0, 0, 255);
}
.dynamic:has(.watched),
.structural:has(> .inserted),
.sibling-anchor:has(+ .sibling-target.active),
.state-anchor:has(input:checked),
.empty-anchor:has(> :empty) {
color: rgb(255, 0, 0);
}
.specificity.other {
color: rgb(0, 0, 255);
}
/* The maximum specificity in the list is used even when that list item
does not match. */
.specificity:has(.specificity-child, #does-not-exist) {
color: rgb(255, 0, 0);
}
</style>
</head>
<body>
<div id="descendant-anchor">
<div class="descendant"><span class="deep"></span></div>
<p class="direct"></p>
</div>
<div id="nonmatching-anchor"><div class="descendant"></div></div>
<h2 id="sibling-query-anchor"></h2>
<p id="adjacent"><span class="inside-adjacent"></span></p>
<p class="later-sibling"></p>
<div id="dynamic" class="dynamic"><span id="dynamic-child"></span></div>
<div id="structural" class="structural"></div>
<div id="sibling-anchor" class="sibling-anchor"></div>
<div id="sibling-target" class="sibling-target"></div>
<div id="state-anchor" class="state-anchor"><input id="checkbox" type="checkbox"></div>
<div id="empty-anchor" class="empty-anchor"><span id="empty-child"></span></div>
<div id="specificity" class="specificity other"><span class="specificity-child"></span></div>
<div id="explicit-outer" class="explicit-outer">
<div id="explicit-scope"><span class="scope-result"></span></div>
</div>
<div id="visited-anchor"><a href=""></a></div>
<script>
"use strict";
const blue = "rgb(0, 0, 255)";
const red = "rgb(255, 0, 0)";
function color(id) {
return getComputedStyle(document.getElementById(id)).color;
}
function syntaxError(selector) {
let threw = false;
try {
document.querySelector(selector);
} catch (error) {
threw = error.name === "SyntaxError";
}
ok(threw, selector + " is rejected as an invalid selector");
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
is(document.querySelector("div:has(.deep)").id,
"descendant-anchor",
"implicit descendant relative selector matches");
is(document.querySelector("div:has(> .direct)").id,
"descendant-anchor",
"leading child combinator matches");
is(document.querySelector("h2:has(+ p .inside-adjacent)").id,
"sibling-query-anchor",
"adjacent sibling subtree matches");
is(document.querySelector("h2:has(+ p + .later-sibling)").id,
"sibling-query-anchor",
"later combinators can move beyond the adjacent sibling subtree");
is(document.querySelector("h2:has(~ .later-sibling)").id,
"sibling-query-anchor",
"subsequent sibling matches");
ok(!document.getElementById("nonmatching-anchor").matches(":has(.deep)"),
"a descendant of the wrong compound does not match");
is(document.querySelector(".inside-adjacent").closest("p:has(.inside-adjacent)").id,
"adjacent",
":has() works through closest()");
syntaxError("div:has()");
syntaxError("div:has(.deep, :definitely-unknown)");
syntaxError("div:has(:has(.deep))");
syntaxError("div:has(::before)");
let explicitScope = document.getElementById("explicit-scope");
is(explicitScope.querySelectorAll(":has(:scope)").length, 0,
"explicit :scope is distinct from the implicit relative anchor");
is(explicitScope.querySelectorAll(
".explicit-outer:has(:scope) .scope-result").length, 1,
"explicit :scope inside :has() refers to the query scoping root");
ok(document.documentElement.matches(":has(:is(:has(*), body))"),
"an invalid nested :has() branch is discarded by a forgiving :is()");
ok(!document.documentElement.matches(":has(:is(:has(*)))"),
"a forgiving list containing only invalid nested :has() matches nothing");
ok(!document.getElementById("visited-anchor").matches(":has(:visited)"),
":visited does not expose history through :has()");
ok(document.getElementById("visited-anchor").matches(":has(:link)"),
":link remains usable inside :has()");
let sheet = document.getElementById("has-styles").sheet;
let index = sheet.insertRule("article:has(> img, + aside .note) {}", sheet.cssRules.length);
is(sheet.cssRules[index].selectorText,
"article:has(> img, + aside .note)",
"relative selector list serialization does not expose the implicit anchor");
sheet.deleteRule(index);
is(color("specificity"), red,
":has() uses the most specific selector in its complete argument list");
is(color("dynamic"), blue, "descendant attribute dependency starts unmatched");
document.getElementById("dynamic-child").classList.add("watched");
is(color("dynamic"), red, "descendant attribute change makes :has() match");
document.getElementById("dynamic-child").classList.remove("watched");
is(color("dynamic"), blue, "descendant attribute change makes :has() stop matching");
is(color("structural"), blue, "child dependency starts unmatched");
let inserted = document.createElement("span");
inserted.className = "inserted";
document.getElementById("structural").appendChild(inserted);
is(color("structural"), red, "child insertion makes :has() match");
inserted.remove();
is(color("structural"), blue, "child removal makes :has() stop matching");
is(color("sibling-anchor"), blue, "sibling dependency starts unmatched");
document.getElementById("sibling-target").classList.add("active");
is(color("sibling-anchor"), red, "following sibling attribute change invalidates anchor");
document.getElementById("sibling-target").classList.remove("active");
is(color("sibling-anchor"), blue, "following sibling can stop matching dynamically");
is(color("state-anchor"), blue, "state dependency starts unmatched");
document.getElementById("checkbox").checked = true;
is(color("state-anchor"), red, "descendant state change invalidates anchor");
document.getElementById("checkbox").checked = false;
is(color("state-anchor"), blue, "descendant state can stop matching dynamically");
is(color("empty-anchor"), red, ":empty inside :has() initially matches");
document.getElementById("empty-child").appendChild(document.createTextNode("text"));
is(color("empty-anchor"), blue, "text insertion invalidates :empty inside :has()");
SimpleTest.finish();
});
</script>
</body>
</html>
@@ -79,7 +79,7 @@ class FasterMakeBackend(CommonBackend, PartialBackend):
.add_pattern_symlink(
prefix,
f.full_path[len(prefix):],
mozpath.join(obj.install_target, path))
path)
else:
self._install_manifests[obj.install_target].add_symlink(
f.full_path,
+1 -1
View File
@@ -481,7 +481,7 @@ class PreprocessedFile(BaseFile):
pp = Preprocessor(defines=self.defines, marker=self.marker)
pp.setSilenceDirectiveWarnings(self.silence_missing_directive_warnings)
with open(self.path, 'rU') as input:
with open(self.path, 'r') as input:
pp.processFile(input=input, output=dest, depfile=deps_out)
dest.close()
-6
View File
@@ -78,12 +78,6 @@ class ToolLauncher(object):
env['PATH'] = '%s;%s' % (vcdir, env['PATH'])
break
# Work around a bug in Python 2.7.2 and lower where unicode types in
# environment variables aren't handled by subprocess.
for k, v in list(env.items()):
if isinstance(v, str):
env[k] = v.encode('utf-8')
print('Executing', ' '.join(cmd), file=errors.out)
errors.out.flush()
return subprocess.call(cmd, env=env)
+183 -267
View File
@@ -5186,13 +5186,6 @@
${EndIf}
${EndIf}
ReadINIStr $R8 $R7 "Install" "QuickLaunchShortcut"
${If} $R8 == "false"
StrCpy $AddQuickLaunchSC "0"
${Else}
StrCpy $AddQuickLaunchSC "1"
${EndIf}
ReadINIStr $R8 $R7 "Install" "DesktopShortcut"
${If} $R8 == "false"
StrCpy $AddDesktopSC "0"
@@ -5812,43 +5805,11 @@
Push $0
!ifndef NONADMIN_ELEVATE
${If} ${AtLeastWinVista}
UAC::IsAdmin
; If the user is not an admin already
${If} "$0" != "1"
UAC::SupportsUAC
; If the system supports UAC
${If} "$0" == "1"
UAC::GetElevationType
; If the user account has a split token
${If} "$0" == "3"
UAC::RunElevated
UAC::Unload
; Nothing besides UAC initialized so no need to call OnEndCommon
Quit
${EndIf}
${EndIf}
${Else}
${GetParameters} $R9
${If} $R9 != ""
ClearErrors
${GetOptions} "$R9" "/UAC:" $0
; If the command line contains /UAC then we need to initialize
; the UAC plugin to use UAC::ExecCodeSegment to execute code in
; the non-elevated context.
${Unless} ${Errors}
UAC::RunElevated
${EndUnless}
${EndIf}
${EndIf}
${EndIf}
!else
${If} ${AtLeastWinVista}
UAC::IsAdmin
; If the user is not an admin already
${If} "$0" != "1"
UAC::SupportsUAC
; If the system supports UAC require that the user elevate
; If the system supports UAC
${If} "$0" == "1"
UAC::GetElevationType
; If the user account has a split token
@@ -5858,41 +5819,69 @@
; Nothing besides UAC initialized so no need to call OnEndCommon
Quit
${EndIf}
${Else}
; Check if UAC is enabled. If the user has turned UAC on or off
; without rebooting this value will be incorrect. This is an
; edgecase that we have to live with when trying to allow
; installing when the user doesn't have privileges such as a public
; computer while trying to also achieve UAC elevation. When this
; happens the user will be presented with the runas dialog if the
; value is 1 and won't be presented with the UAC dialog when the
; value is 0.
ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA"
${If} "$R9" == "1"
; This will display the UAC version of the runas dialog which
; requires a password for an existing user account.
UAC::RunElevated
${If} "$0" == "0" ; Was elevation successful
UAC::Unload
; Nothing besides UAC initialized so no need to call OnEndCommon
Quit
${EndIf}
; Unload UAC since the elevation request was not successful and
; install anyway.
UAC::Unload
${EndIf}
${EndIf}
${Else}
ClearErrors
${${_MOZFUNC_UN}GetParameters} $R9
${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
; If the command line contains /UAC then we need to initialize the UAC
; plugin to use UAC::ExecCodeSegment to execute code in the
; non-elevated context.
${Unless} ${Errors}
UAC::RunElevated
${EndUnless}
${GetParameters} $R9
${If} $R9 != ""
ClearErrors
${GetOptions} "$R9" "/UAC:" $0
; If the command line contains /UAC then we need to initialize
; the UAC plugin to use UAC::ExecCodeSegment to execute code in
; the non-elevated context.
${Unless} ${Errors}
UAC::RunElevated
${EndUnless}
${EndIf}
${EndIf}
!else
UAC::IsAdmin
; If the user is not an admin already
${If} "$0" != "1"
UAC::SupportsUAC
; If the system supports UAC require that the user elevate
${If} "$0" == "1"
UAC::GetElevationType
; If the user account has a split token
${If} "$0" == "3"
UAC::RunElevated
UAC::Unload
; Nothing besides UAC initialized so no need to call OnEndCommon
Quit
${EndIf}
${Else}
; Check if UAC is enabled. If the user has turned UAC on or off
; without rebooting this value will be incorrect. This is an
; edgecase that we have to live with when trying to allow
; installing when the user doesn't have privileges such as a public
; computer while trying to also achieve UAC elevation. When this
; happens the user will be presented with the runas dialog if the
; value is 1 and won't be presented with the UAC dialog when the
; value is 0.
ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA"
${If} "$R9" == "1"
; This will display the UAC version of the runas dialog which
; requires a password for an existing user account.
UAC::RunElevated
${If} "$0" == "0" ; Was elevation successful
UAC::Unload
; Nothing besides UAC initialized so no need to call OnEndCommon
Quit
${EndIf}
; Unload UAC since the elevation request was not successful and
; install anyway.
UAC::Unload
${EndIf}
${EndIf}
${Else}
ClearErrors
${${_MOZFUNC_UN}GetParameters} $R9
${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
; If the command line contains /UAC then we need to initialize the UAC
; plugin to use UAC::ExecCodeSegment to execute code in the
; non-elevated context.
${Unless} ${Errors}
UAC::RunElevated
${EndUnless}
${EndIf}
!endif
@@ -5956,10 +5945,6 @@
!define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall"
Function ${_MOZFUNC_UN}UnloadUAC
${Unless} ${AtLeastWinVista}
Return
${EndUnless}
Push $R9
ClearErrors
@@ -6307,7 +6292,6 @@
*/
!macro _LoggingShortcutsCommon
!insertmacro LogDesktopShortcut
!insertmacro LogQuickLaunchShortcut
!insertmacro LogSMProgramsShortcut
!macroend
!define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon"
@@ -6329,9 +6313,9 @@
/**
* Adds shortcut entries to the shortcuts log ini file. This macro is primarily
* a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and
* LogSMProgramsShortcut macros but it can be used by other code if desired. If
* the value already exists the the value is not written to the file.
* a helper used by the LogDesktopShortcut and LogSMProgramsShortcut macros but
* it can be used by other code if desired. If the value already exists the the
* value is not written to the file.
*
* @param _SECTION_NAME
* The section name to write to in the shortcut log ini file
@@ -6424,38 +6408,6 @@
!verbose pop
!macroend
/**
* Adds a QuickLaunch shortcut entry to the shortcuts log ini file.
*
* @param _FILE_NAME
* The shortcut file name (e.g. shortcut.lnk)
*/
!macro LogQuickLaunchShortcut
!ifndef LogQuickLaunchShortcut
!insertmacro LogShortcut
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall"
Function LogQuickLaunchShortcut
Call LogShortcut
FunctionEnd
!verbose pop
!endif
!macroend
!macro LogQuickLaunchShortcutCall _FILE_NAME
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "QUICKLAUNCH"
Push "${_FILE_NAME}"
Call LogQuickLaunchShortcut
!verbose pop
!macroend
/**
* Adds a Start Menu shortcut entry to the shortcuts log ini file.
*
@@ -6611,10 +6563,6 @@
!define ${_MOZFUNC_UN}SetAppLSPCategories "!insertmacro ${_MOZFUNC_UN}SetAppLSPCategoriesCall"
Function ${_MOZFUNC_UN}SetAppLSPCategories
${Unless} ${AtLeastWinVista}
Return
${EndUnless}
Exch $R9
Push $R8
Push $R7
@@ -6724,8 +6672,7 @@
StrCpy $R5 "false"
${If} ${AtLeastWin7}
${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk"
${Do}
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7"
@@ -6804,8 +6751,7 @@
StrCpy $R5 "false"
${If} ${AtLeastWin7}
${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk"
${Do}
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7"
@@ -6876,8 +6822,7 @@
StrCpy $R9 0
${If} ${AtLeastWin7}
${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk"
${Do}
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7"
@@ -6937,8 +6882,7 @@
StrCpy $R9 0
${If} ${AtLeastWin7}
${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk"
${Do}
${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7"
@@ -7018,132 +6962,109 @@
StrCpy $R3 "false"
${If} ${AtLeastWin7}
; installed shortcuts
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6
${If} ${FileExists} "$R6"
; Update the Start Menu shortcuts' App ID for this application
StrCpy $R2 -1
${Do}
IntOp $R2 $R2 + 1 ; Increment the counter
ClearErrors
ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2"
${If} ${Errors}
${ExitDo}
${EndIf}
${If} ${FileExists} "$SMPROGRAMS\$R5"
ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5"
Pop $R4
${GetLongPath} "$R4" $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$SMPROGRAMS\$R5" "$R8"
Pop $R4
${EndIf}
${EndIf}
${Loop}
; Update the Quick Launch shortcuts' App ID for this application
StrCpy $R2 -1
${Do}
IntOp $R2 $R2 + 1 ; Increment the counter
ClearErrors
ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2"
${If} ${Errors}
${ExitDo}
${EndIf}
${If} ${FileExists} "$QUICKLAUNCH\$R5"
ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5"
Pop $R4
${GetLongPath} "$R4" $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8"
Pop $R4
${EndIf}
${EndIf}
${Loop}
; Update the Start Menu Programs shortcuts' App ID for this application
; installed shortcuts
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6
${If} ${FileExists} "$R6"
; Update the Start Menu shortcuts' App ID for this application
StrCpy $R2 -1
${Do}
IntOp $R2 $R2 + 1 ; Increment the counter
ClearErrors
ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir"
${Unless} ${Errors}
${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7
${Unless} "$R7" == ""
StrCpy $R2 -1
${Do}
IntOp $R2 $R2 + 1 ; Increment the counter
ClearErrors
ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2"
${If} ${Errors}
${ExitDo}
${EndIf}
ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2"
${If} ${Errors}
${ExitDo}
${EndIf}
${If} ${FileExists} "$R7\$R5"
ShellLink::GetShortCutTarget "$R7\$R5"
${If} ${FileExists} "$SMPROGRAMS\$R5"
ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5"
Pop $R4
${GetLongPath} "$R4" $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$SMPROGRAMS\$R5" "$R8"
Pop $R4
${EndIf}
${EndIf}
${Loop}
; Update the Start Menu Programs shortcuts' App ID for this application
ClearErrors
ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir"
${Unless} ${Errors}
${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7
${Unless} "$R7" == ""
StrCpy $R2 -1
${Do}
IntOp $R2 $R2 + 1 ; Increment the counter
ClearErrors
ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2"
${If} ${Errors}
${ExitDo}
${EndIf}
${If} ${FileExists} "$R7\$R5"
ShellLink::GetShortCutTarget "$R7\$R5"
Pop $R4
${GetLongPath} "$R4" $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\$R5" "$R8"
Pop $R4
${GetLongPath} "$R4" $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\$R5" "$R8"
Pop $R4
${EndIf}
${EndIf}
${Loop}
${EndUnless}
${EndIf}
${Loop}
${EndUnless}
${EndIf}
StrCpy $R7 "$QUICKLAUNCH\User Pinned"
StrCpy $R3 "false"
; $R9 = main application executable path
; $R8 = appid
; $R7 = user pinned path
; $R6 = find handle
; $R5 = found filename
; $R4 = GetShortCutTarget result
; TaskBar links
FindFirst $R6 $R5 "$R7\TaskBar\*.lnk"
${Do}
${If} ${FileExists} "$R7\TaskBar\$R5"
ShellLink::GetShortCutTarget "$R7\TaskBar\$R5"
Pop $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\TaskBar\$R5" "$R8"
Pop $R4 ; pop Set result off the stack
StrCpy $R3 "true"
${EndIf}
${EndIf}
ClearErrors
FindNext $R6 $R5
${If} ${Errors}
${ExitDo}
${EndIf}
${Loop}
FindClose $R6
; Start menu links
FindFirst $R6 $R5 "$R7\StartMenu\*.lnk"
${Do}
${If} ${FileExists} "$R7\StartMenu\$R5"
ShellLink::GetShortCutTarget "$R7\StartMenu\$R5"
Pop $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\StartMenu\$R5" "$R8"
Pop $R4 ; pop Set result off the stack
StrCpy $R3 "true"
${EndIf}
${EndIf}
ClearErrors
FindNext $R6 $R5
${If} ${Errors}
${ExitDo}
${EndIf}
${Loop}
FindClose $R6
${EndUnless}
${EndIf}
StrCpy $R7 "$QUICKLAUNCH\User Pinned"
StrCpy $R3 "false"
; $R9 = main application executable path
; $R8 = appid
; $R7 = user pinned path
; $R6 = find handle
; $R5 = found filename
; $R4 = GetShortCutTarget result
; TaskBar links
FindFirst $R6 $R5 "$R7\TaskBar\*.lnk"
${Do}
${If} ${FileExists} "$R7\TaskBar\$R5"
ShellLink::GetShortCutTarget "$R7\TaskBar\$R5"
Pop $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\TaskBar\$R5" "$R8"
Pop $R4 ; pop Set result off the stack
StrCpy $R3 "true"
${EndIf}
${EndIf}
ClearErrors
FindNext $R6 $R5
${If} ${Errors}
${ExitDo}
${EndIf}
${Loop}
FindClose $R6
; Start menu links
FindFirst $R6 $R5 "$R7\StartMenu\*.lnk"
${Do}
${If} ${FileExists} "$R7\StartMenu\$R5"
ShellLink::GetShortCutTarget "$R7\StartMenu\$R5"
Pop $R4
${If} "$R4" == "$R9" ; link path == install path
ApplicationID::Set "$R7\StartMenu\$R5" "$R8"
Pop $R4 ; pop Set result off the stack
StrCpy $R3 "true"
${EndIf}
${EndIf}
ClearErrors
FindNext $R6 $R5
${If} ${Errors}
${ExitDo}
${EndIf}
${Loop}
FindClose $R6
ClearErrors
StrCpy $R9 $R3
@@ -7249,23 +7170,21 @@
Exch $R8 ; stack: $R8, $R9 | $R8 = regpath
Push $R7
${If} ${AtLeastWin7}
${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
; Always create a new AppUserModelID and overwrite the existing one
; for the current installation path.
CityHash::GetCityHash64 "$R9"
Pop $AppUserModelID
${If} $AppUserModelID == "error"
GoTo end
${EndIf}
${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
; Always create a new AppUserModelID and overwrite the existing one
; for the current installation path.
CityHash::GetCityHash64 "$R9"
Pop $AppUserModelID
${If} $AppUserModelID == "error"
GoTo end
${EndIf}
ClearErrors
WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID"
${If} ${Errors}
ClearErrors
WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID"
WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID"
${If} ${Errors}
ClearErrors
WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID"
${If} ${Errors}
StrCpy $AppUserModelID "error"
${EndIf}
StrCpy $AppUserModelID "error"
${EndIf}
${EndIf}
@@ -7351,15 +7270,12 @@
StrCpy $ITaskbarList3 0
; Don't create when running silently.
${Unless} ${Silent}
; This is only supported on Win 7 and above.
${If} ${AtLeastWin7}
System::Call "ole32::CoCreateInstance(g '${CLSID_ITaskbarList}', \
i 0, \
i ${CLSCTX_INPROC_SERVER}, \
g '${IID_ITaskbarList3}', \
*i .s)"
Pop $ITaskbarList3
${EndIf}
System::Call "ole32::CoCreateInstance(g '${CLSID_ITaskbarList}', \
i 0, \
i ${CLSCTX_INPROC_SERVER}, \
g '${IID_ITaskbarList3}', \
*i .s)"
Pop $ITaskbarList3
${EndUnless}
FunctionEnd