Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qt6-webchannel for openSUSE:Factory checked in at 2026-03-28 20:12:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qt6-webchannel (Old) and /work/SRC/openSUSE:Factory/.qt6-webchannel.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qt6-webchannel" Sat Mar 28 20:12:53 2026 rev:35 rq:1342821 version:6.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/qt6-webchannel/qt6-webchannel.changes 2026-02-03 21:28:35.725318445 +0100 +++ /work/SRC/openSUSE:Factory/.qt6-webchannel.new.8177/qt6-webchannel.changes 2026-03-28 20:13:30.673819504 +0100 @@ -1,0 +2,6 @@ +Mon Mar 23 10:37:56 UTC 2026 - Christophe Marin <[email protected]> + +- Update to 6.11.0 + https://www.qt.io/blog/qt-6.11-released + +------------------------------------------------------------------- Old: ---- qtwebchannel-everywhere-src-6.10.2.tar.xz New: ---- qtwebchannel-everywhere-src-6.11.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qt6-webchannel.spec ++++++ --- /var/tmp/diff_new_pack.hYuEqS/_old 2026-03-28 20:13:31.529854834 +0100 +++ /var/tmp/diff_new_pack.hYuEqS/_new 2026-03-28 20:13:31.533854999 +0100 @@ -1,7 +1,7 @@ # # spec file for package qt6-webchannel # -# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,8 +16,8 @@ # -%define real_version 6.10.2 -%define short_version 6.10 +%define real_version 6.11.0 +%define short_version 6.11 %define tar_name qtwebchannel-everywhere-src %define tar_suffix %{nil} # @@ -27,7 +27,7 @@ %endif # Name: qt6-webchannel%{?pkg_suffix} -Version: 6.10.2 +Version: 6.11.0 Release: 0 Summary: Qt 6 WebChannel library License: GPL-2.0-only OR LGPL-3.0-only OR GPL-3.0-only @@ -126,6 +126,9 @@ %if !%{qt6_docs_flavor} +# FIXME this file belongs to examples. It shouldn't be installed in standard prefix +rm %{buildroot}%{_qt6_sharedir}/qt6/webchannel/qwebchannel.js + # CMake files are not needed for plugins rm -r %{buildroot}%{_qt6_cmakedir}/Qt6Qml/QmlPlugins ++++++ qtwebchannel-everywhere-src-6.10.2.tar.xz -> qtwebchannel-everywhere-src-6.11.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/.cmake.conf new/qtwebchannel-everywhere-src-6.11.0/.cmake.conf --- old/qtwebchannel-everywhere-src-6.10.2/.cmake.conf 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/.cmake.conf 2026-03-10 06:38:59.000000000 +0100 @@ -1,6 +1,7 @@ -set(QT_REPO_MODULE_VERSION "6.10.2") +set(QT_REPO_MODULE_VERSION "6.11.0") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1" "QT_NO_QASCONST=1" + "QT_NO_URL_CAST_FROM_STRING=1" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/.tag new/qtwebchannel-everywhere-src-6.11.0/.tag --- old/qtwebchannel-everywhere-src-6.10.2/.tag 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/.tag 2026-03-10 06:38:59.000000000 +0100 @@ -1 +1 @@ -d6f9e63149c6b2246262c656464012beb640a1a7 +71609dbea86e08e4e93ea711c567184d8b0da54e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -16,10 +16,16 @@ # Make sure we use the fixed BASE argument of qt_add_resource. set(QT_USE_FIXED_QT_ADD_RESOURCE_BASE TRUE) -find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core) # special case -find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS Concurrent Quick Test QuickTest WebSockets Widgets) # special case +find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals) + +# This should be called as early as possible, just after find_package(BuildInternals) where it is +# defined. qt_internal_project_setup() +find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core) +find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS Concurrent Quick Test QuickTest + WebSockets Widgets) + if(INTEGRITY) message(NOTICE "Skipping the build as the condition \"NOT INTEGRITY\" is not met.") return() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/REUSE.toml new/qtwebchannel-everywhere-src-6.11.0/REUSE.toml --- old/qtwebchannel-everywhere-src-6.10.2/REUSE.toml 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/REUSE.toml 2026-03-10 06:38:59.000000000 +0100 @@ -4,47 +4,47 @@ path = ["tests/auto/bic/data/*.txt"] precedence = "closest" comment = "test" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only" [[annotations]] path = [".cmake.conf", "**.yaml", "**.json", "**.cfg", ".pri", ".tag"] precedence = "closest" comment = "build system" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "BSD-3-Clause" [[annotations]] path = ["**/.gitattributes", "**.gitignore", "**.gitreview"] precedence = "closest" comment = "version control system. Infrastructure" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" [[annotations]] path = ["examples/**"] comment = "this must be after the build system table because example and snippets take precedence over build system" precedence = "closest" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" [[annotations]] path = ["**/doc/images/**", "**/README*", "**.qdocconf"] comment = "documentation" precedence = "closest" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" [[annotations]] path = ["**.toml", "licenseRule.json"] comment = "infrastructure" precedence = "override" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" [[annotations]] path = ["**/qt_attribution.json"] comment = "documentation" precedence = "override" -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/dependencies.yaml new/qtwebchannel-everywhere-src-6.11.0/dependencies.yaml --- old/qtwebchannel-everywhere-src-6.10.2/dependencies.yaml 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/dependencies.yaml 2026-03-10 06:38:59.000000000 +0100 @@ -1,10 +1,10 @@ dependencies: ../qtbase: - ref: 000d6c62f7880bb8d3054724e8da0b8ae244130e + ref: 8ba7ea4b77a4b8f1948760221e264917ddc9e1c8 required: true ../qtdeclarative: - ref: 09c70541c76659bcd8c49f05841b0e778c9ffd4c + ref: e602a097ca314e9610b1fd3b7dbfa467a868731a required: false ../qtwebsockets: - ref: 2b969cb983d1e22df0e6fc6ece54043942090bd8 + ref: 882f182c8bb5d249ecd97601557ab0e671bdf520 required: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/dist/REUSE.toml new/qtwebchannel-everywhere-src-6.11.0/dist/REUSE.toml --- old/qtwebchannel-everywhere-src-6.10.2/dist/REUSE.toml 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/dist/REUSE.toml 2026-03-10 06:38:59.000000000 +0100 @@ -4,5 +4,5 @@ path = ["*"] precedence = "override" comment = "Licensed as documentation." -SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." +SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/examples.pro new/qtwebchannel-everywhere-src-6.11.0/examples/examples.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/examples.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/examples.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += webchannel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -1,10 +1,11 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -# These are all TEMPLATE = aux -#qt_internal_add_example(nodejs) -#qt_internal_add_example(qwclient) -#qt_internal_add_example(chatclient-html) +qt_internal_add_example(shared) + +qt_internal_add_example(nodejs) +qt_internal_add_example(qwclient) +qt_internal_add_example(chatclient-html) if(TARGET Qt::WebSockets AND NOT ANDROID) qt_internal_add_example(chatserver-cpp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-html/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-html/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-html/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-html/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1 @@ +# Empty file required for supporting installation of example sources. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-html/chatclient-html.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-html/chatclient-html.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-html/chatclient-html.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-html/chatclient-html.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,7 +0,0 @@ -TEMPLATE = aux - -exampleassets.files += \ - chatclient.html - -exampleassets.path = $$[QT_INSTALL_EXAMPLES]/webchannel/chatclient-html -include(../exampleassets.pri) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16) project(qmlchatclient LANGUAGES CXX) -find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick Widgets) +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick WebChannel Widgets) qt_standard_project_setup() @@ -29,7 +29,11 @@ "qmlchatclient.qml" "LoginForm.ui.qml" "MainForm.ui.qml" - "../shared/qwebchannel.js" + "${QT_QWEBCHANNEL_JS_PATH}" +) + +set_source_files_properties("${QT_QWEBCHANNEL_JS_PATH}" PROPERTIES + QT_RESOURCE_ALIAS "qwebchannel.js" ) qt6_add_resources(qmlchatclient "data" @@ -38,3 +42,17 @@ FILES ${data_resource_files} ) + +install(TARGETS qmlchatclient + BUNDLE DESTINATION . + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) +qt_generate_deploy_qml_app_script( + TARGET qmlchatclient + OUTPUT_SCRIPT deploy_script + MACOS_BUNDLE_POST_BUILD + NO_UNSUPPORTED_PLATFORM_ERROR + DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM +) +install(SCRIPT ${deploy_script}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/chatclient-qml.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/chatclient-qml.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/chatclient-qml.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/chatclient-qml.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,17 +0,0 @@ -TEMPLATE = app -TARGET = qmlchatclient - -QT += quick widgets - -SOURCES += main.cpp - -RESOURCES += \ - ../shared/shared.qrc \ - LoginForm.ui.qml \ - MainForm.ui.qml \ - qmlchatclient.qml - -QML_IMPORT_PATH = $$PWD/../shared - -target.path = $$[QT_INSTALL_EXAMPLES]/webchannel/chatclient-qml -INSTALLS += target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/chatclient-qml.qmlproject new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/chatclient-qml.qmlproject --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/chatclient-qml.qmlproject 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/chatclient-qml.qmlproject 1970-01-01 01:00:00.000000000 +0100 @@ -1,39 +0,0 @@ -import QmlProject - -Project { - mainFile: "MainForm.ui.qml" - - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - - JavaScriptFiles { - directory: "." - } - - ImageFiles { - directory: "." - } - - Files { - filter: "qmldir" - directory: "." - } - - Files { - filter: "*.ttf;*.otf" - } - - Environment { - QT_AUTO_SCREEN_SCALE_FACTOR: "1" - } - - qt6Project: true - - /* List of plugin directories passed to QML runtime */ - importPaths: [ ".", "imports" ] - - /* Required for deployment */ - targetDirectory: "/opt/chatclient" -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/qmlchatclient.qml new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/qmlchatclient.qml --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatclient-qml/qmlchatclient.qml 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatclient-qml/qmlchatclient.qml 2026-03-10 06:38:59.000000000 +0100 @@ -7,7 +7,7 @@ import QtQuick.Controls import QtQuick.Layouts import QtWebSockets -import "../shared/qwebchannel.js" as WebChannel +import "qrc:/qwebchannel.js" as WebChannel ApplicationWindow { id: root diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatserver-cpp/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatserver-cpp/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatserver-cpp/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatserver-cpp/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -10,12 +10,6 @@ set(CMAKE_AUTOMOC ON) -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webchannel/chatserver-cpp") - find_package(Qt6 REQUIRED COMPONENTS Core WebChannel WebSockets) qt_add_executable(chatserver @@ -37,7 +31,13 @@ ) install(TARGETS chatserver - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION . + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) +qt_generate_deploy_app_script( + TARGET chatserver + OUTPUT_SCRIPT deploy_script + NO_UNSUPPORTED_PLATFORM_ERROR ) +install(SCRIPT ${deploy_script}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatserver-cpp/chatserver-cpp.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatserver-cpp/chatserver-cpp.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/chatserver-cpp/chatserver-cpp.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/chatserver-cpp/chatserver-cpp.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -TARGET = chatserver - -TEMPLATE = app - -QT += core websockets webchannel -QT -= gui - -CONFIG += console - -SOURCES += main.cpp \ - chatserver.cpp \ - ../shared/websocketclientwrapper.cpp \ - ../shared/websockettransport.cpp - -HEADERS += \ - chatserver.h \ - ../shared/websocketclientwrapper.h \ - ../shared/websockettransport.h - -target.path = $$[QT_INSTALL_EXAMPLES]/webchannel/chatserver-cpp -INSTALLS += target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/exampleassets.pri new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/exampleassets.pri --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/exampleassets.pri 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/exampleassets.pri 1970-01-01 01:00:00.000000000 +0100 @@ -1,19 +0,0 @@ -# This adds the qwebchannel js library to an example, creating a self-contained bundle -jslib = $$PWD/shared/qwebchannel.js - -# This installs all assets including qwebchannel.js, regardless of the source. -exampleassets.files += $$jslib -INSTALLS += exampleassets - -# This code ensures that all assets are present in the build directory. - -!equals(_PRO_FILE_PWD_, $$OUT_PWD) { - # Shadow build, copy all example assets. - assetcopy.files += $$exampleassets.files -} else { - # Just copy jslib - other assets are already in place. - assetcopy.files = $$jslib -} - -assetcopy.path = $$OUT_PWD -COPIES += assetcopy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/nodejs/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/nodejs/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/nodejs/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/nodejs/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1 @@ +# Empty file required for supporting installation of example sources. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/nodejs/nodejs.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/nodejs/nodejs.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/nodejs/nodejs.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/nodejs/nodejs.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,7 +0,0 @@ -TEMPLATE = aux - -exampleassets.files += \ - chatclient.js \ - package.json -exampleassets.path = $$[QT_INSTALL_EXAMPLES]/webchannel/nodejs -include(../exampleassets.pri) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/qwclient/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/qwclient/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/qwclient/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/qwclient/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1 @@ +# Empty file required for supporting installation of example sources. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/qwclient/qwclient.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/qwclient/qwclient.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/qwclient/qwclient.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/qwclient/qwclient.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,9 +0,0 @@ -TEMPLATE = aux - -exampleassets.files += \ - qwclient.js \ - package.json \ - README - -exampleassets.path = $$[QT_INSTALL_EXAMPLES]/webchannel/qwclient -include(../exampleassets.pri) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1 @@ +# Empty file required for supporting installation of example sources. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/qwebchannel.js new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/qwebchannel.js --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/qwebchannel.js 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/qwebchannel.js 1970-01-01 01:00:00.000000000 +0100 @@ -1,456 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected], author Milian Wolff <[email protected]> -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -// Qt-Security score:critical reason:data-parser - -"use strict"; - -var QWebChannelMessageTypes = { - signal: 1, - propertyUpdate: 2, - init: 3, - idle: 4, - debug: 5, - invokeMethod: 6, - connectToSignal: 7, - disconnectFromSignal: 8, - setProperty: 9, - response: 10, -}; - -var QWebChannel = function(transport, initCallback, converters) -{ - if (typeof transport !== "object" || typeof transport.send !== "function") { - console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." + - " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send)); - return; - } - - var channel = this; - this.transport = transport; - - var converterRegistry = - { - Date : function(response) { - if (typeof response === "string" - && response.match( - /^-?\d+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d*)?([-+\u2212](\d{2}):(\d{2})|Z)?$/)) { - var date = new Date(response); - if (!isNaN(date)) - return date; - } - return undefined; // Return undefined if current converter is not applicable - } - }; - - this.usedConverters = []; - - this.addConverter = function(converter) - { - if (typeof converter === "string") { - if (converterRegistry.hasOwnProperty(converter)) - this.usedConverters.push(converterRegistry[converter]); - else - console.error("Converter '" + converter + "' not found"); - } else if (typeof converter === "function") { - this.usedConverters.push(converter); - } else { - console.error("Invalid converter object type " + typeof converter); - } - } - - if (Array.isArray(converters)) { - for (const converter of converters) - this.addConverter(converter); - } else if (converters !== undefined) { - this.addConverter(converters); - } - - this.send = function(data) - { - if (typeof(data) !== "string") { - data = JSON.stringify(data); - } - channel.transport.send(data); - } - - this.transport.onmessage = function(message) - { - var data = message.data; - if (typeof data === "string") { - data = JSON.parse(data); - } - switch (data.type) { - case QWebChannelMessageTypes.signal: - channel.handleSignal(data); - break; - case QWebChannelMessageTypes.response: - channel.handleResponse(data); - break; - case QWebChannelMessageTypes.propertyUpdate: - channel.handlePropertyUpdate(data); - break; - default: - console.error("invalid message received:", message.data); - break; - } - } - - this.execCallbacks = {}; - this.execId = 0; - this.exec = function(data, callback) - { - if (!callback) { - // if no callback is given, send directly - channel.send(data); - return; - } - if (channel.execId === Number.MAX_VALUE) { - // wrap - channel.execId = Number.MIN_VALUE; - } - if (data.hasOwnProperty("id")) { - console.error("Cannot exec message with property id: " + JSON.stringify(data)); - return; - } - data.id = channel.execId++; - channel.execCallbacks[data.id] = callback; - channel.send(data); - }; - - this.objects = {}; - - this.handleSignal = function(message) - { - var object = channel.objects[message.object]; - if (object) { - object.signalEmitted(message.signal, message.args); - } else { - console.warn("Unhandled signal: " + message.object + "::" + message.signal); - } - } - - this.handleResponse = function(message) - { - if (!message.hasOwnProperty("id")) { - console.error("Invalid response message received: ", JSON.stringify(message)); - return; - } - channel.execCallbacks[message.id](message.data); - delete channel.execCallbacks[message.id]; - } - - this.handlePropertyUpdate = function(message) - { - message.data.forEach(data => { - var object = channel.objects[data.object]; - if (object) { - object.propertyUpdate(data.signals, data.properties); - } else { - console.warn("Unhandled property update: " + data.object + "::" + data.signal); - } - }); - channel.exec({type: QWebChannelMessageTypes.idle}); - } - - this.debug = function(message) - { - channel.send({type: QWebChannelMessageTypes.debug, data: message}); - }; - - channel.exec({type: QWebChannelMessageTypes.init}, function(data) { - for (const objectName of Object.keys(data)) { - new QObject(objectName, data[objectName], channel); - } - - // now unwrap properties, which might reference other registered objects - for (const objectName of Object.keys(channel.objects)) { - channel.objects[objectName].unwrapProperties(); - } - - if (initCallback) { - initCallback(channel); - } - channel.exec({type: QWebChannelMessageTypes.idle}); - }); -}; - -function QObject(name, data, webChannel) -{ - this.__id__ = name; - webChannel.objects[name] = this; - - // List of callbacks that get invoked upon signal emission - this.__objectSignals__ = {}; - - // Cache of all properties, updated when a notify signal is emitted - this.__propertyCache__ = {}; - - var object = this; - - // ---------------------------------------------------------------------- - - this.unwrapQObject = function(response) - { - for (const converter of webChannel.usedConverters) { - var result = converter(response); - if (result !== undefined) - return result; - } - - if (response instanceof Array) { - // support list of objects - return response.map(qobj => object.unwrapQObject(qobj)) - } - if (!(response instanceof Object)) - return response; - - if (!response["__QObject*__"] || response.id === undefined) { - var jObj = {}; - for (const propName of Object.keys(response)) { - jObj[propName] = object.unwrapQObject(response[propName]); - } - return jObj; - } - - var objectId = response.id; - if (webChannel.objects[objectId]) - return webChannel.objects[objectId]; - - if (!response.data) { - console.error("Cannot unwrap unknown QObject " + objectId + " without data."); - return; - } - - var qObject = new QObject( objectId, response.data, webChannel ); - qObject.destroyed.connect(function() { - if (webChannel.objects[objectId] === qObject) { - delete webChannel.objects[objectId]; - // reset the now deleted QObject to an empty {} object - // just assigning {} though would not have the desired effect, but the - // below also ensures all external references will see the empty map - // NOTE: this detour is necessary to workaround QTBUG-40021 - Object.keys(qObject).forEach(name => delete qObject[name]); - } - }); - // here we are already initialized, and thus must directly unwrap the properties - qObject.unwrapProperties(); - return qObject; - } - - this.unwrapProperties = function() - { - for (const propertyIdx of Object.keys(object.__propertyCache__)) { - object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); - } - } - - function addSignal(signalData, isPropertyNotifySignal) - { - var signalName = signalData[0]; - var signalIndex = signalData[1]; - object[signalName] = { - connect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to connect to signal " + signalName); - return; - } - - object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; - object.__objectSignals__[signalIndex].push(callback); - - // only required for "pure" signals, handled separately for properties in propertyUpdate - if (isPropertyNotifySignal) - return; - - // also note that we always get notified about the destroyed signal - if (signalName === "destroyed" || signalName === "destroyed()" || signalName === "destroyed(QObject*)") - return; - - // and otherwise we only need to be connected only once - if (object.__objectSignals__[signalIndex].length == 1) { - webChannel.exec({ - type: QWebChannelMessageTypes.connectToSignal, - object: object.__id__, - signal: signalIndex - }); - } - }, - disconnect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to disconnect from signal " + signalName); - return; - } - // This makes a new list. This is important because it won't interfere with - // signal processing if a disconnection happens while emittig a signal - object.__objectSignals__[signalIndex] = (object.__objectSignals__[signalIndex] || []).filter(function(c) { - return c != callback; - }); - if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { - // only required for "pure" signals, handled separately for properties in propertyUpdate - webChannel.exec({ - type: QWebChannelMessageTypes.disconnectFromSignal, - object: object.__id__, - signal: signalIndex - }); - } - } - }; - } - - /** - * Invokes all callbacks for the given signalname. Also works for property notify callbacks. - */ - function invokeSignalCallbacks(signalName, signalArgs) - { - var connections = object.__objectSignals__[signalName]; - if (connections) { - connections.forEach(function(callback) { - callback.apply(callback, signalArgs); - }); - } - } - - this.propertyUpdate = function(signals, propertyMap) - { - // update property cache - for (const propertyIndex of Object.keys(propertyMap)) { - var propertyValue = propertyMap[propertyIndex]; - object.__propertyCache__[propertyIndex] = this.unwrapQObject(propertyValue); - } - - for (const signalName of Object.keys(signals)) { - // Invoke all callbacks, as signalEmitted() does not. This ensures the - // property cache is updated before the callbacks are invoked. - invokeSignalCallbacks(signalName, signals[signalName]); - } - } - - this.signalEmitted = function(signalName, signalArgs) - { - invokeSignalCallbacks(signalName, this.unwrapQObject(signalArgs)); - } - - function addMethod(methodData) - { - var methodName = methodData[0]; - var methodIdx = methodData[1]; - - // Fully specified methods are invoked by id, others by name for host-side overload resolution - var invokedMethod = methodName[methodName.length - 1] === ')' ? methodIdx : methodName - - object[methodName] = function() { - var args = []; - var callback; - var errCallback; - for (var i = 0; i < arguments.length; ++i) { - var argument = arguments[i]; - if (typeof argument === "function") - callback = argument; - else - args.push(argument); - } - - var result; - // during test, webChannel.exec synchronously calls the callback - // therefore, the promise must be constucted before calling - // webChannel.exec to ensure the callback is set up - if (!callback && (typeof(Promise) === 'function')) { - result = new Promise(function(resolve, reject) { - callback = resolve; - errCallback = reject; - }); - } - - webChannel.exec({ - "type": QWebChannelMessageTypes.invokeMethod, - "object": object.__id__, - "method": invokedMethod, - "args": args - }, function(response) { - if (response !== undefined) { - var result = object.unwrapQObject(response); - if (callback) { - (callback)(result); - } - } else if (errCallback) { - (errCallback)(); - } - }); - - return result; - }; - } - - function bindGetterSetter(propertyInfo) - { - var propertyIndex = propertyInfo[0]; - var propertyName = propertyInfo[1]; - var notifySignalData = propertyInfo[2]; - // initialize property cache with current value - // NOTE: if this is an object, it is not directly unwrapped as it might - // reference other QObject that we do not know yet - object.__propertyCache__[propertyIndex] = propertyInfo[3]; - - if (notifySignalData) { - if (notifySignalData[0] === 1) { - // signal name is optimized away, reconstruct the actual name - notifySignalData[0] = propertyName + "Changed"; - } - addSignal(notifySignalData, true); - } - - Object.defineProperty(object, propertyName, { - configurable: true, - get: function () { - var propertyValue = object.__propertyCache__[propertyIndex]; - if (propertyValue === undefined) { - // This shouldn't happen - console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); - } - - return propertyValue; - }, - set: function(value) { - if (value === undefined) { - console.warn("Property setter for " + propertyName + " called with undefined value!"); - return; - } - object.__propertyCache__[propertyIndex] = value; - var valueToSend = value; - webChannel.exec({ - "type": QWebChannelMessageTypes.setProperty, - "object": object.__id__, - "property": propertyIndex, - "value": valueToSend - }); - } - }); - - } - - // ---------------------------------------------------------------------- - - data.methods.forEach(addMethod); - - data.properties.forEach(bindGetterSetter); - - data.signals.forEach(function(signal) { addSignal(signal, false); }); - - Object.assign(object, data.enums); -} - -QObject.prototype.toJSON = function() { - if (this.__id__ === undefined) return {}; - return { - id: this.__id__, - "__QObject*__": true - }; -}; - -//required for use with nodejs -if (typeof module === 'object') { - module.exports = { - QWebChannel: QWebChannel - }; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/shared.qrc new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/shared.qrc --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/shared/shared.qrc 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/shared/shared.qrc 1970-01-01 01:00:00.000000000 +0100 @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/shared"> - <file>qwebchannel.js</file> - </qresource> -</RCC> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -7,12 +7,6 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webchannel/standalone") - find_package(Qt6 REQUIRED COMPONENTS Core Gui WebChannel WebSockets Widgets) qt_add_executable(standalone @@ -41,6 +35,15 @@ Qt::Widgets ) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qwebchannel.js + COMMAND ${CMAKE_COMMAND} -E copy + ${QT_QWEBCHANNEL_JS_PATH} + ${CMAKE_CURRENT_BINARY_DIR}/qwebchannel.js + DEPENDS ${QT_QWEBCHANNEL_JS_PATH} + VERBATIM +) + if (NOT CMAKE_CURRENT_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/index.html @@ -52,15 +55,6 @@ ) endif() -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qwebchannel.js - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/../shared/qwebchannel.js - ${CMAKE_CURRENT_BINARY_DIR}/qwebchannel.js - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../shared/qwebchannel.js - VERBATIM -) - add_custom_target(output_target ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/index.html @@ -68,14 +62,3 @@ ) add_dependencies(standalone output_target) - -install(TARGETS standalone - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/index.html ${CMAKE_CURRENT_BINARY_DIR}/qwebchannel.js - DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/main.cpp new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/main.cpp --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/main.cpp 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/main.cpp 2026-03-10 06:38:59.000000000 +0100 @@ -19,11 +19,6 @@ { QApplication app(argc, argv); - QFileInfo jsFileInfo(QDir::currentPath() + "/qwebchannel.js"); - - if (!jsFileInfo.exists()) - QFile::copy(":/qtwebchannel/qwebchannel.js",jsFileInfo.absoluteFilePath()); - // setup the QWebSocketServer QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode); if (!server.listen(QHostAddress::LocalHost, 12345)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/standalone.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/standalone.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/standalone/standalone.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/standalone/standalone.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,28 +0,0 @@ -QT += gui webchannel widgets websockets - -CONFIG += warn_on - -SOURCES += \ - main.cpp \ - dialog.cpp \ - ../shared/websockettransport.cpp \ - ../shared/websocketclientwrapper.cpp - -HEADERS += \ - core.h \ - dialog.h \ - ../shared/websockettransport.h \ - ../shared/websocketclientwrapper.h - -FORMS += \ - dialog.ui - -DEFINES += "BUILD_DIR=\"\\\""$$OUT_PWD"\\\"\"" - -exampleassets.files += \ - index.html -exampleassets.path = $$[QT_INSTALL_EXAMPLES]/webchannel/standalone -include(../exampleassets.pri) - -target.path = $$[QT_INSTALL_EXAMPLES]/webchannel/standalone -INSTALLS += target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/webchannel.pro new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/webchannel.pro --- old/qtwebchannel-everywhere-src-6.10.2/examples/webchannel/webchannel.pro 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/examples/webchannel/webchannel.pro 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -TEMPLATE = subdirs -qtHaveModule(websockets) { - SUBDIRS += chatserver-cpp \ - chatclient-qml - qtHaveModule(widgets) { - SUBDIRS += standalone - } -} - -SUBDIRS += nodejs \ - qwclient \ - chatclient-html - -EXAMPLE_FILES += \ - shared diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/CMakeLists.txt new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/CMakeLists.txt --- old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/CMakeLists.txt 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/CMakeLists.txt 2026-03-10 06:38:59.000000000 +0100 @@ -1,6 +1,26 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause +if(QT6_INSTALL_QT_SHAREDIR) + set(INSTALL_WEBCHANNEL_SHAREDIR "${QT6_INSTALL_QT_SHAREDIR}/webchannel") +else() + set(INSTALL_WEBCHANNEL_SHAREDIR "${INSTALL_QT_SHAREDIR}/webchannel") +endif() + +include(CMakePackageConfigHelpers) + +set(target "WebChannel") +set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}") +qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix}) +qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) + +configure_package_config_file( + Qt6WebChannelExtras.cmake.in + "${config_build_dir}/Qt6WebChannelExtras.cmake" + INSTALL_DESTINATION "${config_install_dir}" + PATH_VARS INSTALL_WEBCHANNEL_SHAREDIR +) + qt_internal_add_module(WebChannel SOURCES qmetaobjectpublisher.cpp qmetaobjectpublisher_p.h @@ -8,22 +28,22 @@ qwebchannelabstracttransport.cpp qwebchannelabstracttransport.h signalhandler_p.h qwebchannelglobal.h + qwebchannel.js DEFINES QT_NO_CONTEXTLESS_CONNECT LIBRARIES Qt::CorePrivate -) - -set(resource_file "../../examples/webchannel/shared/qwebchannel.js") -set_source_files_properties(${resource_file} PROPERTIES - QT_RESOURCE_ALIAS "qwebchannel.js" + EXTRA_CMAKE_FILES + "${config_build_dir}/Qt6WebChannelExtras.cmake" + EXTRA_CMAKE_INCLUDES + Qt6WebChannelExtras.cmake ) qt_internal_add_resource(WebChannel "resources" PREFIX "/qtwebchannel/" FILES - ${resource_file} + qwebchannel.js ) if(TARGET Qt::Qml) @@ -36,3 +56,7 @@ doc/qtwebchannel.qdocconf ) +install(FILES qwebchannel.js + DESTINATION "${INSTALL_WEBCHANNEL_SHAREDIR}") +file(COPY qwebchannel.js + DESTINATION "${QT_BUILD_DIR}/${INSTALL_WEBCHANNEL_SHAREDIR}/") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/Qt6WebChannelExtras.cmake.in new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/Qt6WebChannelExtras.cmake.in --- old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/Qt6WebChannelExtras.cmake.in 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/Qt6WebChannelExtras.cmake.in 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1,6 @@ +# Copyright (C) 2025 Menlo Systems GmbH; author Arno Rehn <[email protected]> +# SPDX-License-Identifier: BSD-3-Clause + +@PACKAGE_INIT@ + +set(QT_QWEBCHANNEL_JS_PATH "@PACKAGE_INSTALL_WEBCHANNEL_SHAREDIR@/qwebchannel.js") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/qmetaobjectpublisher.cpp new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/qmetaobjectpublisher.cpp --- old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/qmetaobjectpublisher.cpp 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/qmetaobjectpublisher.cpp 2026-03-10 06:38:59.000000000 +0100 @@ -963,7 +963,7 @@ } else if (result.canConvert<QVariantList>()) { // recurse and potentially wrap contents of the array // *don't* use result.toList() as that *only* works for QVariantList and QStringList! - // Also, don't use QSequentialIterable (yet), since that seems to trigger QTBUG-42016 + // Also, don't use QMetaSequence::Iterable (yet), since that seems to trigger QTBUG-42016 // in certain cases. // additionally, when there's a direct converter to QVariantList, use that one via convert // but recover when conversion fails and fall back to the .value<QVariantList> conversion diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/qwebchannel.js new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/qwebchannel.js --- old/qtwebchannel-everywhere-src-6.10.2/src/webchannel/qwebchannel.js 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/src/webchannel/qwebchannel.js 2026-03-10 06:38:59.000000000 +0100 @@ -0,0 +1,456 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected], author Milian Wolff <[email protected]> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser + +"use strict"; + +var QWebChannelMessageTypes = { + signal: 1, + propertyUpdate: 2, + init: 3, + idle: 4, + debug: 5, + invokeMethod: 6, + connectToSignal: 7, + disconnectFromSignal: 8, + setProperty: 9, + response: 10, +}; + +var QWebChannel = function(transport, initCallback, converters) +{ + if (typeof transport !== "object" || typeof transport.send !== "function") { + console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." + + " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send)); + return; + } + + var channel = this; + this.transport = transport; + + var converterRegistry = + { + Date : function(response) { + if (typeof response === "string" + && response.match( + /^-?\d+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d*)?([-+\u2212](\d{2}):(\d{2})|Z)?$/)) { + var date = new Date(response); + if (!isNaN(date)) + return date; + } + return undefined; // Return undefined if current converter is not applicable + } + }; + + this.usedConverters = []; + + this.addConverter = function(converter) + { + if (typeof converter === "string") { + if (converterRegistry.hasOwnProperty(converter)) + this.usedConverters.push(converterRegistry[converter]); + else + console.error("Converter '" + converter + "' not found"); + } else if (typeof converter === "function") { + this.usedConverters.push(converter); + } else { + console.error("Invalid converter object type " + typeof converter); + } + } + + if (Array.isArray(converters)) { + for (const converter of converters) + this.addConverter(converter); + } else if (converters !== undefined) { + this.addConverter(converters); + } + + this.send = function(data) + { + if (typeof(data) !== "string") { + data = JSON.stringify(data); + } + channel.transport.send(data); + } + + this.transport.onmessage = function(message) + { + var data = message.data; + if (typeof data === "string") { + data = JSON.parse(data); + } + switch (data.type) { + case QWebChannelMessageTypes.signal: + channel.handleSignal(data); + break; + case QWebChannelMessageTypes.response: + channel.handleResponse(data); + break; + case QWebChannelMessageTypes.propertyUpdate: + channel.handlePropertyUpdate(data); + break; + default: + console.error("invalid message received:", message.data); + break; + } + } + + this.execCallbacks = {}; + this.execId = 0; + this.exec = function(data, callback) + { + if (!callback) { + // if no callback is given, send directly + channel.send(data); + return; + } + if (channel.execId === Number.MAX_VALUE) { + // wrap + channel.execId = Number.MIN_VALUE; + } + if (data.hasOwnProperty("id")) { + console.error("Cannot exec message with property id: " + JSON.stringify(data)); + return; + } + data.id = channel.execId++; + channel.execCallbacks[data.id] = callback; + channel.send(data); + }; + + this.objects = {}; + + this.handleSignal = function(message) + { + var object = channel.objects[message.object]; + if (object) { + object.signalEmitted(message.signal, message.args); + } else { + console.warn("Unhandled signal: " + message.object + "::" + message.signal); + } + } + + this.handleResponse = function(message) + { + if (!message.hasOwnProperty("id")) { + console.error("Invalid response message received: ", JSON.stringify(message)); + return; + } + channel.execCallbacks[message.id](message.data); + delete channel.execCallbacks[message.id]; + } + + this.handlePropertyUpdate = function(message) + { + message.data.forEach(data => { + var object = channel.objects[data.object]; + if (object) { + object.propertyUpdate(data.signals, data.properties); + } else { + console.warn("Unhandled property update: " + data.object + "::" + data.signal); + } + }); + channel.exec({type: QWebChannelMessageTypes.idle}); + } + + this.debug = function(message) + { + channel.send({type: QWebChannelMessageTypes.debug, data: message}); + }; + + channel.exec({type: QWebChannelMessageTypes.init}, function(data) { + for (const objectName of Object.keys(data)) { + new QObject(objectName, data[objectName], channel); + } + + // now unwrap properties, which might reference other registered objects + for (const objectName of Object.keys(channel.objects)) { + channel.objects[objectName].unwrapProperties(); + } + + if (initCallback) { + initCallback(channel); + } + channel.exec({type: QWebChannelMessageTypes.idle}); + }); +}; + +function QObject(name, data, webChannel) +{ + this.__id__ = name; + webChannel.objects[name] = this; + + // List of callbacks that get invoked upon signal emission + this.__objectSignals__ = {}; + + // Cache of all properties, updated when a notify signal is emitted + this.__propertyCache__ = {}; + + var object = this; + + // ---------------------------------------------------------------------- + + this.unwrapQObject = function(response) + { + for (const converter of webChannel.usedConverters) { + var result = converter(response); + if (result !== undefined) + return result; + } + + if (response instanceof Array) { + // support list of objects + return response.map(qobj => object.unwrapQObject(qobj)) + } + if (!(response instanceof Object)) + return response; + + if (!response["__QObject*__"] || response.id === undefined) { + var jObj = {}; + for (const propName of Object.keys(response)) { + jObj[propName] = object.unwrapQObject(response[propName]); + } + return jObj; + } + + var objectId = response.id; + if (webChannel.objects[objectId]) + return webChannel.objects[objectId]; + + if (!response.data) { + console.error("Cannot unwrap unknown QObject " + objectId + " without data."); + return; + } + + var qObject = new QObject( objectId, response.data, webChannel ); + qObject.destroyed.connect(function() { + if (webChannel.objects[objectId] === qObject) { + delete webChannel.objects[objectId]; + // reset the now deleted QObject to an empty {} object + // just assigning {} though would not have the desired effect, but the + // below also ensures all external references will see the empty map + // NOTE: this detour is necessary to workaround QTBUG-40021 + Object.keys(qObject).forEach(name => delete qObject[name]); + } + }); + // here we are already initialized, and thus must directly unwrap the properties + qObject.unwrapProperties(); + return qObject; + } + + this.unwrapProperties = function() + { + for (const propertyIdx of Object.keys(object.__propertyCache__)) { + object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); + } + } + + function addSignal(signalData, isPropertyNotifySignal) + { + var signalName = signalData[0]; + var signalIndex = signalData[1]; + object[signalName] = { + connect: function(callback) { + if (typeof(callback) !== "function") { + console.error("Bad callback given to connect to signal " + signalName); + return; + } + + object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; + object.__objectSignals__[signalIndex].push(callback); + + // only required for "pure" signals, handled separately for properties in propertyUpdate + if (isPropertyNotifySignal) + return; + + // also note that we always get notified about the destroyed signal + if (signalName === "destroyed" || signalName === "destroyed()" || signalName === "destroyed(QObject*)") + return; + + // and otherwise we only need to be connected only once + if (object.__objectSignals__[signalIndex].length == 1) { + webChannel.exec({ + type: QWebChannelMessageTypes.connectToSignal, + object: object.__id__, + signal: signalIndex + }); + } + }, + disconnect: function(callback) { + if (typeof(callback) !== "function") { + console.error("Bad callback given to disconnect from signal " + signalName); + return; + } + // This makes a new list. This is important because it won't interfere with + // signal processing if a disconnection happens while emittig a signal + object.__objectSignals__[signalIndex] = (object.__objectSignals__[signalIndex] || []).filter(function(c) { + return c != callback; + }); + if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { + // only required for "pure" signals, handled separately for properties in propertyUpdate + webChannel.exec({ + type: QWebChannelMessageTypes.disconnectFromSignal, + object: object.__id__, + signal: signalIndex + }); + } + } + }; + } + + /** + * Invokes all callbacks for the given signalname. Also works for property notify callbacks. + */ + function invokeSignalCallbacks(signalName, signalArgs) + { + var connections = object.__objectSignals__[signalName]; + if (connections) { + connections.forEach(function(callback) { + callback.apply(callback, signalArgs); + }); + } + } + + this.propertyUpdate = function(signals, propertyMap) + { + // update property cache + for (const propertyIndex of Object.keys(propertyMap)) { + var propertyValue = propertyMap[propertyIndex]; + object.__propertyCache__[propertyIndex] = this.unwrapQObject(propertyValue); + } + + for (const signalName of Object.keys(signals)) { + // Invoke all callbacks, as signalEmitted() does not. This ensures the + // property cache is updated before the callbacks are invoked. + invokeSignalCallbacks(signalName, signals[signalName]); + } + } + + this.signalEmitted = function(signalName, signalArgs) + { + invokeSignalCallbacks(signalName, this.unwrapQObject(signalArgs)); + } + + function addMethod(methodData) + { + var methodName = methodData[0]; + var methodIdx = methodData[1]; + + // Fully specified methods are invoked by id, others by name for host-side overload resolution + var invokedMethod = methodName[methodName.length - 1] === ')' ? methodIdx : methodName + + object[methodName] = function() { + var args = []; + var callback; + var errCallback; + for (var i = 0; i < arguments.length; ++i) { + var argument = arguments[i]; + if (typeof argument === "function") + callback = argument; + else + args.push(argument); + } + + var result; + // during test, webChannel.exec synchronously calls the callback + // therefore, the promise must be constucted before calling + // webChannel.exec to ensure the callback is set up + if (!callback && (typeof(Promise) === 'function')) { + result = new Promise(function(resolve, reject) { + callback = resolve; + errCallback = reject; + }); + } + + webChannel.exec({ + "type": QWebChannelMessageTypes.invokeMethod, + "object": object.__id__, + "method": invokedMethod, + "args": args + }, function(response) { + if (response !== undefined) { + var result = object.unwrapQObject(response); + if (callback) { + (callback)(result); + } + } else if (errCallback) { + (errCallback)(); + } + }); + + return result; + }; + } + + function bindGetterSetter(propertyInfo) + { + var propertyIndex = propertyInfo[0]; + var propertyName = propertyInfo[1]; + var notifySignalData = propertyInfo[2]; + // initialize property cache with current value + // NOTE: if this is an object, it is not directly unwrapped as it might + // reference other QObject that we do not know yet + object.__propertyCache__[propertyIndex] = propertyInfo[3]; + + if (notifySignalData) { + if (notifySignalData[0] === 1) { + // signal name is optimized away, reconstruct the actual name + notifySignalData[0] = propertyName + "Changed"; + } + addSignal(notifySignalData, true); + } + + Object.defineProperty(object, propertyName, { + configurable: true, + get: function () { + var propertyValue = object.__propertyCache__[propertyIndex]; + if (propertyValue === undefined) { + // This shouldn't happen + console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); + } + + return propertyValue; + }, + set: function(value) { + if (value === undefined) { + console.warn("Property setter for " + propertyName + " called with undefined value!"); + return; + } + object.__propertyCache__[propertyIndex] = value; + var valueToSend = value; + webChannel.exec({ + "type": QWebChannelMessageTypes.setProperty, + "object": object.__id__, + "property": propertyIndex, + "value": valueToSend + }); + } + }); + + } + + // ---------------------------------------------------------------------- + + data.methods.forEach(addMethod); + + data.properties.forEach(bindGetterSetter); + + data.signals.forEach(function(signal) { addSignal(signal, false); }); + + Object.assign(object, data.enums); +} + +QObject.prototype.toJSON = function() { + if (this.__id__ === undefined) return {}; + return { + id: this.__id__, + "__QObject*__": true + }; +}; + +//required for use with nodejs +if (typeof module === 'object') { + module.exports = { + QWebChannel: QWebChannel + }; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebchannel-everywhere-src-6.10.2/src/webchannelquick/qqmlwebchannel.cpp new/qtwebchannel-everywhere-src-6.11.0/src/webchannelquick/qqmlwebchannel.cpp --- old/qtwebchannel-everywhere-src-6.10.2/src/webchannelquick/qqmlwebchannel.cpp 2026-01-22 21:37:57.000000000 +0100 +++ new/qtwebchannel-everywhere-src-6.11.0/src/webchannelquick/qqmlwebchannel.cpp 2026-03-10 06:38:59.000000000 +0100 @@ -170,6 +170,22 @@ } } +/*! + \property QQmlWebChannel::registeredObjects + + This property holds the list of objects which should be accessible to remote clients. + + The objects must have the attached id property set to an identifier, under which the + object is then known on the HTML side. + + Once registered, all signals and property changes are automatically propagated to the clients. + Public invokable methods, including slots, are also accessible to the clients. + + If one needs to register objects which are not available when the component is created, use the + imperative registerObjects method. + + \sa registerObjects(), id +*/ QQmlListProperty<QObject> QQmlWebChannel::registeredObjects() { return QQmlListProperty<QObject>(this, nullptr, registeredObjects_append, @@ -223,6 +239,14 @@ return channel->d_func()->registeredObjects.clear(); } +/*! + \property QQmlWebChannel::transports + + This property holds a list of transport objects, which implement QWebChannelAbstractTransport. + The transports are used to talk to the remote clients. + + \sa connectTo(), disconnectFrom() +*/ QQmlListProperty<QObject> QQmlWebChannel::transports() { return QQmlListProperty<QObject>(this, nullptr, transports_append, transports_count,
