qt.webChannelTransport undefined in QWebEngineView - javascript

I ran into a problem using QWebChannel for accessing an object from JavaScript. I'm currently using Qt5.4.2.
Here's my CPP code :
myObject::myObject(QWidget *parent)
: QMainWindow(parent)
{
QWebEngineView* m_pView = new QWebEngineView(this);
QWebChannel channel;
channel.registerObject(QString("myObject"), this);
m_pView->load(QUrl("file:///D:/index.html"));
setCentralWidget(m_pView);
}
In my index.html, I am including qwebchannel.js :
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
And in my javascript file, I am trying to retrieve my object like this :
new QWebChannel(qt.webChannelTransport, function(channel) {
var myObject = channel.objects.myObject;
});
However, I get the following error in the console :
Error: qt is not defined
I also tried to replace it with navigator.qtWebChannelTransport but I got :
Error: transport is not defined
Can somebody tell me what did I do wrong? Thanks.
Edit : Is qt.webChannelTransport only accessible with Qt5.5? It seems to be the case when I read the doc of QWebEnginePage::setWebChannel...

You must setWebChannel before load url

Thats correct.
QWebChannel integration with QWebEngine is only available from version 5.5 as stated here by Milian, the main developer of the module.

You have to google qwebchannel.js to get the default code (it's a lot of code actually) or get it from out of Qt's directories somehow. I put mine under <qrc>/qtwebchannel/qwebchannel.js. Then make sure you import it as a regular javascript into your index.html but with source as "qrc:/qtwebchannel/qwebchannel.js". I had your exact error earlier today, and something I did fixed it - was probably including that script.

For others having the same issue but using Qt 5.5+, make sure you have QT += webchannel in your .pro file.

Related

Cannot add external JavaScript file to React application

I have read all advices how to add external JavaScript file to React application but no one works for me. I'll describe my situation. I have created a tutorial React project and it works fine. Now I want to show a data that I get from server side in some grid , say, jqgrid. I have a JavaScript file that has a function showGrid() to show the grid. So I need to add this file to the project. More precisely I have a React component ShowInGrid and in
render()
method of it I write
let contents = this.state.loading
? <p><em>Loading...</em></p>
: ShowInGrid.renderGrid(this.state.data);
and then
static rendersGrid(data) {
return (
showGrid(data)
);
where showGrid is a function from JavaScript file. To reference to this file I used several ways:
in componentDidMount method I added
var script = document.createElement('script');
script.src = // path of external javascript file.
script.class = "external-script
document.body.appendChild(script);
I get a message
'showGrid' is not defined no-undef
I tried to use
import ScriptTag from 'react-script-tag';
with
< ScriptTag isHydrating={true} type="text/javascript" src="http://my path to js-file">
but I get the same result.
So I really need to know what's wrong and how properly to add JavaScript file to app. A real working example will be really appreciated.

"Cookies not defined" in standalone js-cookie javascript lib?

I am not a javascript guru, but try to use js-cookie.
I included the script: https://github.com/js-cookie/js-cookie: I downloaded it (LINK), and put it in my own js file on the server.
I then include it in a test file and read some cookie, but it keeps showing me the error "Cookies is not defined" in the browser console. What am I doing wrong :( ?
Code:
<html><head>
<script type="javascript" src="https://server/cookies.js"></script>
<script>
console.log("ALL COOKIES: " + Cookies.get());
</script></head>
<body></body>
I've not used the library, but a quick look at the source code shows that it exports Cookies with an uppercase C.
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
So try using the correct case.
console.log("ALL COOKIES: " + window.Cookies.get());
Also, everything on window is global. So you can simplify the code to this.
console.log("ALL COOKIES: " + Cookies.get());
Next time, in the JavaScript console on the browser. Just type window and enter to see what variables are global. You can also call it directly in the console to see what happens Cookies should print out a JavaScript object with descriptions of what functions it has.
If it's undefined then it wasn't loaded or is not global.
UPDATED:
The browser is not loading the JavaScript library because the mime-type is wrong. You have to use application/javascript as here:
<script type="application/javascript" src="https://server/cookies.js"></script>
You are using wrong versions of cookie.js on different routes/pages
Use the Latest
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
If it is not working, then try
<script src="https://cdn.jsdelivr.net/npm/js-cookie#rc/dist/js.cookie.min.js"></script>
Quick fix : Just use window. before calling it
window.Cookies.get()
Inspired by #ucMedia's answer, you can add the following line at the beginning of a script to fix any issues.
var Cookies = window.Cookies;

How to include JavaScript file into JSP?

I have the following script tag in my JSP file:
<script src="/js/CCTUtil.js"></script>
with the following function in it:
function disableButton(buttonID) {
document.getElementById(buttonID).setAttribute("disabled", "true");
return true;
}
and in my jsp I call it with:
onchange="disableButton('datasourceForm:cancel');
datasourceForm:cancel is just the ID, so don't worry about that.
This works if I hardcode the JS function in my JSP, but when exporting it to a file, it doesn't work. It recognizes the valid filepath (otherwise the server throws an exception) so it can see the file just fine, but when testing it in Internet Explorer the error is "Object expected", and points to the end of the JSP file, which of course isn't telling of anything.
Help please?
The SRC must not be correct then. Are you sure you have set the path correctly? It's not supposed to be "../js/CCTUtil.js" is it?
Instead of including script file, directly add javascript function in the jsp file.
Then try, if you are getting the same issue, might be some issue with javascript or ur id datasourceForm:cancel

Sharing TinyMCE plugin across multiple applications

I'm using CakePHP 2.4.7 and the TinyMCE plugin from CakeDC.
I set up my CakePHP core along with the plugin in a shared location on my server so that multiple applications can access it. This keeps me from having to update multiple copies of TinyMCE. Everything was working well until I migrated to a new server and updated software.
The new server is running Apache 2.4 instead of 2.2 and using mod_ruid2 instead of suexec.
I now get this error when trying to load the editor:
Fatal Error (4): syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in [/xyz/Plugin/TinyMCE/webroot/js/tiny_mce/tiny_mce.js, line 1]
How should I start debugging this?
Workaround Attempt
I tried adding a symlink from an application's webroot to TinyMCE's plugin webroot. This works in that it loads the js file and the editor, but then TinyMCE plugins are working on the wrong current directory and file management would not be separated.
The problem is the AssetDispatcher filter, it includes css and js files using PHPs include() statement, causing the files to be sent through the PHP parser, where it will stumble over the occurrences of <? in the TinyMCE script.
See https://github.com/.../2.4.7/lib/Cake/Routing/Filter/AssetDispatcher.php#L159-L160
A very annoying, and, since it's undocumented and non-optional, dangerous behavior if you ask me.
Custom asset dispatcher
In case you want to continue to use a plugin asset dispatcher, extend the built in one, and reimplement the AssetDispatcher::_deliverAsset() method with the include functionality removed. Of course this is kinda annoying, maintenance wise, but it's a pretty quick fix.
Something like:
// app/Routing/Filter/MyAssetDispatcher.php
App::uses('AssetDispatcher', 'Routing/Filter');
class MyAssetDispatcher extends AssetDispatcher {
protected function _deliverAsset(CakeResponse $response, $assetFile, $ext) {
// see the source of your CakePHP core for the
// actual code that you'd need to reimpelment
ob_start();
$compressionEnabled = Configure::read('Asset.compress') && $response->compress();
if ($response->type($ext) == $ext) {
$contentType = 'application/octet-stream';
$agent = env('HTTP_USER_AGENT');
if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
$contentType = 'application/octetstream';
}
$response->type($contentType);
}
if (!$compressionEnabled) {
$response->header('Content-Length', filesize($assetFile));
}
$response->cache(filemtime($assetFile));
$response->send();
ob_clean();
// instead of the possible `include()` in the original
// methods source, use `readfile()` only
readfile($assetFile);
if ($compressionEnabled) {
ob_end_flush();
}
}
}
// app/Config/bootstrap.php
Configure::write('Dispatcher.filters', array(
'MyAssetDispatcher', // instead of AssetDispatcher
// ...
));
See also http://book.cakephp.org/2.0/en/development/dispatch-filters.html
Don't just disable short open tags
I'm just guessig here, but the reason why it was working on your other server probably is that short open tags (ie <?) where disabled. However even if that is the problem on your new server, this isn't something you should rely on, the assets are still being served using include(), and you most probably don't want to check all your third party CSS/JS for possible PHP code injections on every update.

Include remoted Library (API 4.5 Mapy.cz) to Google Chrome Extension

I am confused. I'am trying to make little chrome extension (popup) and I need connect to remoted API.
This is, what I would use, if it is a standard web page:
<script type="text/javascript" src="http://api4.mapy.cz/loader.js"></script>
<script type="text/javascript">Loader.load();</script>
I experimented with including new element script to head (not works for me). But I couldn't believe, there is no easier way...
Please, show me the best way.
EDIT:
Linking the API loader is fine and works. Thanks to #serg. So, my code of popup looks like this:
<script type="text/javascript" src="http://api4.mapy.cz/loader.js"></script>
<script type="text/javascript">
Loader.load();
var center = SMap.Coords.fromWGS84(16.61574, 49.20315);
</script>
Object Loader is defined and it is OK. Loader should load the whole API either object SMap. But SMap is undefined. What next?
If you need to make ajax requests to this remote API, you need to list API domain in the permissions in your manifest:
{
"permissions": [
"http://api4.mapy.cz/"
],
}
Finally I ask developer from Mapy.cz and they gave the solution. Instead of using Loader.load() which cause including additional script and async load - use this way:
Loader.async = true;
Loader.load(null, null, function(){
alert(123); // it works...
// custom code calling objects etc. from API
// ...
});
Final Example of usage

Categories