diff --git a/Repository.mk b/Repository.mk index 97e3e5eb25f8..3fc103ba0757 100644 --- a/Repository.mk +++ b/Repository.mk @@ -443,6 +443,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \ localebe1 \ log \ lng \ + $(call gb_Helper_optional,SCRIPTING,$(if $(ENABLE_QUICKJS),jsprov)) \ $(if $(filter $(OS),MACOSX),macbe1) \ $(if $(MERGELIBS),merged) \ migrationoo2 \ diff --git a/scripting/Library_jsprov.mk b/scripting/Library_jsprov.mk new file mode 100644 index 000000000000..6a49315972c2 --- /dev/null +++ b/scripting/Library_jsprov.mk @@ -0,0 +1,34 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Library_Library,jsprov)) + +$(eval $(call gb_Library_set_componentfile,jsprov,scripting/source/jsprov/jsprov,services)) + +$(eval $(call gb_Library_use_sdk_api,jsprov)) + +$(eval $(call gb_Library_set_include,jsprov,\ + $$(INCLUDE) \ + -I$(SRCDIR)/scripting/source/inc \ +)) + +$(eval $(call gb_Library_use_libraries,jsprov,\ + comphelper \ + cppu \ + cppuhelper \ + jsuno \ + sal \ + singleprov \ +)) + +$(eval $(call gb_Library_add_exception_objects,jsprov,\ + scripting/source/jsprov/loader \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/scripting/Module_scripting.mk b/scripting/Module_scripting.mk index 2c52f6656b03..aad81a0e2fdc 100644 --- a/scripting/Module_scripting.mk +++ b/scripting/Module_scripting.mk @@ -37,6 +37,7 @@ $(eval $(call gb_Module_add_targets,scripting,\ Package_ScriptsPython \ Pyuno_mailmerge \ ) \ + $(if $(ENABLE_QUICKJS),Library_jsprov) \ Library_basprov \ Library_dlgprov \ Library_protocolhandler \ diff --git a/scripting/README.md b/scripting/README.md index 0bfe4d184572..988d1484c3ac 100644 --- a/scripting/README.md +++ b/scripting/README.md @@ -41,6 +41,10 @@ C++ implementation of the `LanguageScriptProvider` UNO service for Basic C++ implementation of the `DialogProvider` UNO service used for loading UNO dialogs from various languages +- `source/jsprov` + +C++ implementation of the `LanguageScriptProvider` UNO service for JavaScript using QuickJS. + - `source/pyprov` `LanguageScriptProvider` for Python diff --git a/scripting/source/jsprov/jsprov.component b/scripting/source/jsprov/jsprov.component new file mode 100644 index 000000000000..893b5cf55e31 --- /dev/null +++ b/scripting/source/jsprov/jsprov.component @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/scripting/source/jsprov/loader.cxx b/scripting/source/jsprov/loader.cxx new file mode 100644 index 000000000000..e012351cc1f6 --- /dev/null +++ b/scripting/source/jsprov/loader.cxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include + +#include + +#include +#include + +namespace +{ +class ScriptWrapper : public cppu::WeakImplHelper +{ +public: + ScriptWrapper(const OUString& sScript) + : m_sScript(sScript) + { + } + + // XScript + css::uno::Any SAL_CALL invoke(const css::uno::Sequence& aParams, + css::uno::Sequence& aOutParamIndex, + css::uno::Sequence& aOutParam) override; + +private: + OUString m_sScript; +}; + +class JsProvScriptFactory : public singleprovider::SingleScriptFactory +{ + OUString getLanguageName() const override; + OUString getExtension() const override; + css::uno::Reference + getScript(css::uno::Reference xContext, const OUString& sName, + std::string_view sSource) const override; + bool appMightExecute(const OUString& sAppName) const override; + OUString getExampleMacro() const override; +}; + +OUString JsProvScriptFactory::getLanguageName() const { return "JavaScript"; } + +OUString JsProvScriptFactory::getExtension() const { return ".js"; } + +css::uno::Reference +JsProvScriptFactory::getScript(css::uno::Reference, const OUString&, + std::string_view sSource) const +{ + return new ScriptWrapper(OStringToOUString(sSource, RTL_TEXTENCODING_UTF8)); +} + +bool JsProvScriptFactory::appMightExecute(const OUString& sAppName) const +{ + return sAppName.startsWithIgnoreAsciiCase("js.") || sAppName.startsWithIgnoreAsciiCase("node."); +} + +OUString JsProvScriptFactory::getExampleMacro() const +{ + return u"let context = uno.componentContext;\n" + "let desktop = uno.idl.com.sun.star.frame.theDesktop(context);\n" + "let frame = desktop.getCurrentFrame();\n" + "let controller = frame.getController();\n" + "let model = controller.getModel();\n" + "let text = model.getText();\n" + "\n" + "text.getEnd().setString(\"Hello, world!\");\n"_ustr; +} + +css::uno::Any SAL_CALL ScriptWrapper::invoke(const css::uno::Sequence&, + css::uno::Sequence&, + css::uno::Sequence&) +{ + jsuno::execute(m_sScript); + + return css::uno::Any(); +} +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +scripting_JavaScriptProviderImpl_get_implementation(css::uno::XComponentContext* pContext, + css::uno::Sequence const&) +{ + css::uno::Reference xProvider + = singleprovider::ScriptProvider::create(pContext, std::make_shared()); + xProvider->acquire(); + return xProvider.get(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */