Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcollator_wasm.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#include "qcollator_p.h"
6#include "qstringlist.h"
7#include "qstring.h"
8
9#include <emscripten/val.h>
10
12
13// This backend implements collation on top of the JavaScript Intl.Collator API.
14//
15// Note: Intl.Collator exposes only compare(); it has no equivalent of ICU's
16// sort keys. sortKey() therefore falls back to calling compare() and does
17// not provide a performance benefit.
19{
21
22 // Build the Intl.Collator options object from the QCollator settings.
23 // The Intl.Collator sensitivity option maps to case/accent handling:
24 // "variant" - case- and accent-sensitive (Qt::CaseSensitive)
25 // "accent" - accent-sensitive, case-insensitive (Qt::CaseInsensitive)
26 emscripten::val collatorOptions = emscripten::val::object();
27 if (options.testFlag(Opt::NumericSort))
28 collatorOptions.set("numeric", true);
29 collatorOptions.set("sensitivity",
30 options.testFlag(Opt::CaseInsensitive) ? "accent" : "variant");
31 if (options.testFlag(Opt::IgnorePunctuation))
32 collatorOptions.set("ignorePunctuation", true);
33
34 // An empty/undefined locale list makes Intl.Collator use the host's
35 // default locale; otherwise pass the BCP 47 tag from the QLocale.
36 const QString bcp47 = locale.bcp47Name();
37 const emscripten::val locales = bcp47.isEmpty()
38 ? emscripten::val::undefined()
39 : emscripten::val(bcp47.toStdString());
40
41 const emscripten::val intl = emscripten::val::global("Intl");
42 collator = new emscripten::val(intl["Collator"].new_(locales, collatorOptions));
43
44 dirty = false;
45}
46
48{
49 delete collator;
51}
52
53namespace {
54// Shared comparison core for QCollator::compare() and QCollatorSortKey::compare().
55// An undefined \a collator selects a plain code-unit comparison (used for the C
56// locale); otherwise the strings are ordered by the given Intl.Collator. Returns a
57// result normalized to the -1/0/+1 range QCollator uses.
58int compareImpl(const emscripten::val &collator, QStringView s1, QStringView s2,
59 Qt::CaseSensitivity cs)
60{
61 if (s1.isEmpty())
62 return s2.isEmpty() ? 0 : -1;
63 if (s2.isEmpty())
64 return +1;
65 if (collator.isUndefined())
66 return s1.compare(s2, cs);
67
68 const int result = collator.call<int>("compare",
69 s1.toString().toStdString(), s2.toString().toStdString());
70 return result < 0 ? -1 : (result > 0 ? 1 : 0);
71}
72} // unnamed namespace
73
74int QCollator::compare(QStringView s1, QStringView s2) const
75{
76 if (!d)
77 d = new QCollatorPrivate(QLocale().collation());
78
79 if (d->isC())
80 return compareImpl(emscripten::val::undefined(), s1, s2, caseSensitivity());
81
82 d->ensureInitialized();
83 return compareImpl(*d->collator, s1, s2, caseSensitivity());
84}
85
86QCollatorSortKey QCollator::sortKey(const QString &string) const
87{
88 if (!d)
89 d = new QCollatorPrivate(QLocale().collation());
90
91 // Create a sort key which captures the string and the collator. Note
92 // that this does not provide a performance benefit, but does implement
93 // correct sorting.
94 QCollatorSortKeyWasm key;
95 key.string = string;
96 if (!d->isC()) {
97 d->ensureInitialized();
98 key.collator = *d->collator;
99 }
100 return QCollatorPrivate::sortKeyFromData(std::move(key));
101}
102
103int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const noexcept
104{
105 return compareImpl(d->m_key.collator, d->m_key.string, otherKey.d->m_key.string, Qt::CaseSensitive);
106}
107
108QT_END_NAMESPACE
CollatorType collator
Definition qcollator_p.h:90
Combined button and popup list for selecting options.
const CollatorType NoCollator
Definition qcollator_p.h:71