I'm trying that when the user enters a command in the Web console, I get this command in the script of my addon before to be executed?
For example, when the user enters the command line "screenshot --fullpage" this command to be sent to a function of the script of my addon before being executed.
I did some research but I only found an event on the opening of the web console.
https://developer.mozilla.org/en-US/docs/Observer_Notifications#Developer_tools
Solution posted here - https://discourse.mozilla-community.org/t/firefox-addon-event-on-a-specific-command-line/6028/10?u=noitidart
Alrighty here we go, this works:
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var tmp = {};
Cu.import("resource://devtools/client/shared/DeveloperToolbar.jsm", tmp);
var gcliInit = require('devtools/shared/gcli/commands/index');
var { TargetFactory } = require("devtools/client/framework/target");
var a = new tmp.DeveloperToolbar(window, document.getElementById("developer-toolbar"));
var sysTarget= TargetFactory.forTab(a._chromeWindow.gBrowser.selectedTab);
gcliInit.getSystem(sysTarget).then(
system => {
console.log('system:',system);
system.addItems([{
name: 'greet',
description: 'Show a greeting',
params: [{
name: 'name',
type: 'string',
description: 'The name to greet'
}],
returnType: 'string',
exec: function(args, context) {
return 'Hello, ' + args.name;
}
}]);
},
y => console.error('y:',y)
);
Note, the path changes in Firefox 45. So this code is for Fx45+ prior to this you would use resource://gre/modules/devtools/Loader.jsm instead of resource://devtools/shared/Loader.jsm.
TargetFactor was the key component I was missing, it's important, it's got these methods:
Object { forTab: function (), forRemoteTab: function (), forWorker: function (), isKnownTab: function () }
Related
I have got to the point where I can click a button on a card and show my app, but I dont know how to pass the board information to my app.
Steps:
In trello, I click on card.. then the power up button. It works, as I see this
Code:
const callback = function (t) {
return t.modal({
url: '../public/index.html',
fullscreen: true,
});
};
const t = window.TrelloPowerUp.initialize({
'card-buttons': function (t, options) {
return [
{
text: 'Hello World',
callback: callback,
},
];
},
});
In docs I see there's an args key that passes an object.
" // optional arguments to be passed to the iframe as query parameters
// access later with t.arg('text')
args: { text: 'Hello' }," - https://developer.atlassian.com/cloud/trello/power-ups/ui-functions/modal/
How do I get either my board info into args.. or use window.TrelloPowerUp.initialize or window.TrelloPowerUp.iframe within the modal?
I am creating a project where I need to take a user input - pass it through a function and return the new value to the user - seems simple enough. I am new to async functions and have read everything I possibly can, and can't works out if there's a more fundamental issue I am missing. I will show the basic code, and then what I wish to achieve. I believe the issue, is that I am returning back the status of the function rather than the value, but just can't work it out.
Basic Code:
ipcMain.on('gpt3', (event, args) => {
async function gpt3(args) {
generateResponse('james', 'hello world'); // Takes a user's name & input and recieves a response from a python file.
event.reply('textRecieve', 'hello world'); // Sends 'Hello World' to the user (ipcRenderer 'textRecieve')
}
gpt3(args);
})
async function generateResponse(name, text) {
let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
let content = "";
try {
testshell.on('message', function (message) {
console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
return message; // attempting to return the 'Message' from the python file
});
} catch (error) {
console.log("You've f*cked it somewhere my friend");
console.log(error);
}
}
Python Script:
import sys
name = sys.argv[1]
text = sys.argv[2]
print(f'Python File: {name} Text: {text}')
sys.stdout.flush()
Returns: (as expected)
> Executing task: npm run start <
> electron-quick-start#1.0.0 start
> electron .
Python File: james Text: hello world
What I'd Like it to do:
ipcMain.on('gpt3', (event, args) => {
async function gpt3(args) {
message = generateResponse('james', 'hello world'); // Takes a user's name & input and recieves a response from a python file, retunring the message to the 'message' variable.
console.log(message);
event.reply('textRecieve', 'message would send here'); // Sends the 'Message' to the user (ipcRenderer 'textRecieve')
}
gpt3(args);
})
async function generateResponse(name, text) {
let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
let content = ""
try {
testshell.on('message', function (message) {
console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
return message; // attempting to return the 'Message' from the python file
});
} catch (error) {
console.log("You've f*cked it somewhere my friend")
console.log(error)
}
return content; // content needs to be message instead due to async nature it returns empty string
}
Returns:
> Executing task: npm run start <
> electron-quick-start#1.0.0 start
> electron .
Promise { '' }
Python File: james Text: hello world
TLDR; I would like to take the 'message' generated through 'generateResponse()' and pass it through to my 'event.reply()'. Instead, I am receiving what I believe to be the status of the Promise. Any help would be greatly appreciated. Thanks
You should resolve the promise first.
ipcMain.on('gpt3', (event, args) => {
async function gpt3(args) {
const message = await generateResponse('james', 'hello world');
console.log(message);
event.reply('textRecieve', 'message would send here'); // Sends the 'Message' to the user (ipcRenderer 'textRecieve')
}
gpt3(args);
})
async function generateResponse(name, text) {
let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
let content = ""
try {
testshell.on('message', function (message) {
console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
content = message;
});
} catch (error) {
console.log("You've f*cked it somewhere my friend")
console.log(error)
}
return content; // content needs to be message instead due to async nature it returns empty string
}
Okay, so there were a few problems here... but the main was node.js 'non-ability' to pass variables around when 'asynchronous'. with node.js being new to me, I can't lie and say I was confused. Hopefully, the following link to a great workaround/method and my working code will be able to help someone:
https://stackoverflow.com/a/23667087/10246221
Code:
ipcMain - nested within app.whenReady().
ipcMain.on('gpt3', (event, input) => {
gpt3Async(event, input, function(result) {
event.reply('textRecieve', result);
console.log('gpt3Async: '+ result);
})
})
Code:
Generic 'nested' Function - free-floating around 'main.js' or 'index.js'.
function gpt3Async(event, input, callback) {
console.log('input: ' + input)
let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: ['elliott' ,input]});
testshell.on('message', function (message) {
callback(message);
});
}
Code: Python Script 'text_echo.py' - in my case within a 'python' subdirectory.
import sys
name = sys.argv[1]
text = sys.argv[2]
print(f'Python File: {name} Text: {text}')
#sys.stdout.flush()
sys.stdout.flush()
For anyone working on a project where you need input and output for python scripts, this will help you out. also make sure you turn on the following:
webPreferences: {
//preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
sandbox: false,
},
BUT!, please be aware of the security implications this will have on your code, More info is available here: https://stackoverflow.com/a/57507392 & https://electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content & much more so do some reading if this is an important project...
Okay, An explainer, or at least something that blew my mind as a beginner... . The way I finally understood it was through the example link:
https://stackoverflow.com/a/23667087/10246221
for some reason, it hadn't clicked with me that functions could be nested within functions like this, all in one line. For someone who is used to JS or node.js this may seem fundamental, but seeing as this is a first-time project to me, and maybe others - if still using python code. Hopefully, this may help!
ipcMain.on('gpt3', (event, input) => { gpt3Async(event, input, function(result) { event.reply('textRecieve', result); console.log('gpt3Async: '+ result);})})
I am using a WebView to load a local HTML file that contains the callback -
function onReward(data){
console.log("onReward: " + data.earnedThisSession);
Survey.postMessage(data.earnedThisSession);
}
This callback gets triggered when a user completes an action, I am currently facing two problems
The data.earnedThisSession returned by the function differs from every user and I want to get this as a variable in my dart code to reward my user
My WebView dependency is not printing console messages in my debug console
This is my JavascriptChannel -
final Set<JavascriptChannel> jsChannels = [
JavascriptChannel(
name: 'Survey',
onMessageReceived: (JavascriptMessage message) {
print(message.message);
}),
].toSet();
This is my WebviewScaffold -
FutureBuilder<String>(
future: _loadLocalHTML(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(),
body: WebView(
initialUrl: Uri.dataFromString(
snapshot.data,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'),
).toString(),
javascriptChannels: jsChannels,
javascriptMode: JavascriptMode.unrestricted,
),
);
}
How do I use evalJavascript in this to fetch my reward data?
Changing Survey.postMessage() to window.Survey.postMessage() may work. Im not sure how to use evalJavascipt with WebviewScaffold, i'm using like this:
final _webView = new FlutterWebviewPlugin();
final Set<JavascriptChannel> jsChannels = [
JavascriptChannel(
name: 'Survey',
onMessageReceived: (JavascriptMessage message) {
print(message.message);
}),
].toSet();
_webView.launch(url, jsChannels);
_webView.onStateChanged.listen((event) {
if (event.type == WebViewState.finishLoad) {
_webView.evalJavascript('Your Js Code' +
'window.Survey.postMessage("Your Return Mes.")');
}
});
I have just discovered the gulp-prompt task. While it makes it easy to prompt the user in different ways, the examples don't hint at how to make use of the user's input. For instance I would like to offer two setups (e.g. CDN-hosted or local assets) to the user and run my tasks conditionally. How can you do that in Gulp? This could save me from looking into a Yeoman generator.
Exemple
...
...
var inject = require('gulp-inject');
var cdnizer = require('gulp-cdnizer');
gulp.task('mytask', function(){
var target = gulp.src('./src/index.html');
return gulp.src('*')
.pipe(prompt.prompt({
type: 'input',
name: 'type',
message: 'What you like to do? [cdn/assets]'
}, function(res){
var sources;
if(res.type === 'cdn'){
sources = ...
target.pipe(inject(sources))
.pipe(gulp.dest('./src'));
}else{
target.pipe(cdnizer({...});
}
}));
});
This is another implementation. It will ask you to choose the task with a keyboard
gulp.task('default', function() {
var taskNames = [];
for (var taskName in gulp.tasks) {
if (gulp.tasks.hasOwnProperty(taskName)) {
taskNames.push(taskName);
}
}
return gulp.src('*').pipe(
prompt.prompt({
type: 'checkbox',
name: 'tasks',
message: 'Choose task name',
choices: taskNames
}, function(res){
//value is in res.task (the name option gives the key)
console.log(res);
res.tasks.forEach(function(taskName){
console.log(taskName);
gulp.tasks[taskName].fn();
});
}));
});
I'm making a jQuery console and I'm using an array filled with the available commands to validate the user's input--so, for example, if they enter help, if help is in array.name, then continue to the next bit of code.
The problem is that I want to display a message such as "that command does not exist" when the filter fails entirely, as in help is not in the array at all. Here is my code so far:
var commands = [
{ 'name': 'help',
'desc': 'display information about all available commands or a singular command',
'args': 'command-name' },
{ 'name': 'info',
'desc': 'display information about this console and its purpose' },
{ 'name': 'authinfo',
'desc': 'display information about me, the creator' },
{ 'name': 'clear',
'desc': 'clear the console' },
{ 'name': 'opensite',
'desc': 'open a website',
'args': 'url' },
{ 'name': 'calc',
'desc': 'calculate math equations',
'args': 'math-equation' },
{ 'name': 'instr',
'desc': 'instructions for using the console' }
];
function detect(cmd) { // function takes the value of an <input> on the page
var cmd = cmd.toLowerCase(); // just in case they typed the command in caps (I'm lazy)
commands.filter(function(command) {
if(command.name == cmd) {
switch(cmd) {
// do stuff
}
}
else {
alert("That command was not found."); // this fires every time command.name != cmd
}
}
}
I have a jsFiddle with (almost) all the code if need be.
http://jsfiddle.net/abluescarab/dga9D/
The else statement fires every time the command name isn't found--which is a lot, since it's looping through the array.
Is there a way to display a message if the command name is not found anywhere in the array while using filter?
Thanks in advance, apologies if I didn't make sense and for the wall of code, and I am open to suggestions of alternative ways to do this.
function get_command(command_name) {
var results = {};
for (var key in commands) (function(name, desc, command) {
if (name == command_name) (function() {
results = command;
}());
}(commands[key]["name"], commands[key]["desc"], commands[key]));
return (results);
};
get_command("help");
and not switch is try filter method function:
commands.filter = (function(command, success_callback, fail_callback) {
if (get_command(command)["name"]) (function() {
success_callback();
}());
else (function() {
fail_callback();
}());
});
commands.filter("help", function() {
console.log("enter help command source :)");
}, function() {
console.log("hey help command???");
});
take it easy.