How to dynamically change what's exposed in a preload script? - electron

I have a BrowserWindow with a preload script.
I want to expose different things in the preload script depending on what page I have loaded.
In my app, either I load page A which gets navigated to page B, or I load page B from the beginning.
I was considering passing additional arguments to my preload via:
{
preload: "path_to_preload.js",
additionalArguments: ["onPageB"]
}
And then my preload can do:
const onPageB = process.argv.find(arg => arg === "onPageB");
And then I set up my preload script based on what page B needs.
However, my preload script can be loaded with page A initially, so onPageB will be false, and then it's stuck at false even when I navigate to page B.
What I really need is to dynamically respond to navigations. (Ideally, I would be able to dynamically switch out preload scripts, but I don't think that's supported, or is possible from an architectural standpoint).
To detect navigations, normally, I would do:
getMyWebContents().on("did-navigate", (e, url) => ...);
But I can't use WebContents from the Renderer process.
I can obviously query what page I'm on via ipcRenderer.invoke, but I can't just do that on load. I need to do that when the page navigates as well, which seems to suggest I have to detect that from the main process, and then let my preload script know that.
But how can I do that. Is executeJavaScript a solution here where I call a function in my preload to trigger the changes? Not sure if that will work correctly, or is even a good solution.

Electron developer mentioned that preload scripts get reexecuted for every navigation (which retrospectively is obvious).
Thus, we can just access location.href in the preload and figure out what page we're on.

Related

Load Only Part of an Ember App at Once

I am building an ember app and it is starting to get large. Is there any way to do lazy loading of the ember files so that it does take 10+ seconds to load when the user first hits the site? For example since I have several logically separate modules as part of the site, I could load the modules as they are accessed. I am using ruby on rails and the ember-rails gem.
If you think about what Ember is actually doing to render that code, you can understand why it is slow. Suppose you're creating 2k view instances, and rendering 2k templates. Templates that for the most part are doing very little. Especially if you don't care about data binding.
For a first stab, let's stop rendering through templates. This code uses itemViewClass to render each item with a custom view instead of the view used internally by each.
// Use with {{each item in items itemViewClass=App.SpanView}}
App.SpanView = Em.View.extend({
render: function(buffer) {
buffer.push("<span>"+this.get('content')+"</span>\n");
}
});
JSBin: http://jsbin.com/enapec/35/edit66
With render over-ridden, we need to interact with the render buffer ourselves.
Even faster would be getting rid of the view entirely. I think there are two ways to do this. You could create a custom view with a render method that loops over all the items, and pushes each element onto the buffer. I think given the previous example you can get that going yourself.
Another simple option is to use a helper. A dumb helper like this is more difficult to wire up for re-rendering when the list changes, but sometimes it is the right solution.
// Use with {{eachInSpan items}}
Em.Handlebars.registerBoundHelper('eachInSpan', function (items) {
return (
new Handlebars.SafeString(
items.map(function (i) {
return '<span>'+i+'</span>';
})
)
);
});
Live JSBin: http://jsbin.com/enapec/34/edit
Lastly, you could do this in jQuery with didInsertElement and the afterRender queue. I don't recommend it though.
Ember.RenderBuffer gathers information regarding the a view and generates the final representation. Ember.RenderBuffer will generate HTML which can be pushed to the DOM.
FYI here is the RenderBuffer API
DEFINED IN
MODULE : Ember-views
I am also new bee but I got this from some resource. Thanks.
On this Keynote on Embercamp London 2016, #wycats and #tomdale talk about the plans for improving Ember with slicing and dicing of the app. They talk about loading only what it's needed for that particular route. This is going to be great. I think that's what you wanted :)
https://www.periscope.tv/w/1mrGmzPBvQqJy#

is there any ready example of firefox addon that can manipulate site content with js/css?

I know there are many tutorials but they concentrate on xul, and manipulating menus and examples are overcrowded with features.
What I need is a simple extension that will for example add a red border to all <body> elements of every page I'm visiting and js would show me alert when a page is finished loading. Just to show that it is working and I will have a point to start learning from.
I know that there are ready extensions like greasemonkey and user css but what I intend to do is to first make such functionality raw, without overhead of yet another extension. And second to have ha proof of concept code so I can learn other features of firefox api.
I know how to write chrome/opera extension. I know all the languages needed, and how to make a mock extension, so it show up in firefox addons list. Vut the problem is that I don't know what to put where to get to the content of actual web page.
I know that there is a file called main.js that I'm supposed to put somewhere with code like this:
var data = require("self").data;
var pageMod = require("page-mod");
pageMod.PageMod({
include: "*",
contentScriptFile: data.url("my_script.js"),
contentStyleFile: data.url("my_style.css")
});
And that begin to look familiar, like in Chrome., my script code:
window.addEventListener("load", function() {
alert("hello there!");
}, true);
But I don't know where to put these files. Are there some default location, or must I set some configuration file to let know the api where main.js is ?
I know that there are projects to make such css/js based extension simpler, like jetpack - but that still creates overhead. I want to learn, but also don't waste my time and create something useful while doing that based on the knowlegde I have from chrome API.
edit:
I found this tutorial: https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/Accessing_the_DOM - but there is nothing on where to put these files there is no example extension using these features.
edit2: https://github.com/mozilla/addon-sdk/tree/master/examples - there is no link for these in mozdev examples, one must search this thru google
Are you still in need of a ready made example?
Here is a bootstrap addon template that does exactly this. You just need to edit the addDiv and removeDiv functions for starters.
https://gist.github.com/Noitidart/9287185
It's called the Add-on SDK. Start here

WinJS: is there any way to pass parameters to x-ms-webview?

I'm developing a Windows Store App, and need to pass parameters to a x-ms-webview control in one page. The code (won't work, just for illustration) should look like:
In the webview host page:
element.querySelector('#webview').myArray= [1, 2, 3];
And in the web view content page:
var arr = window.external.mayArray;
I've tried to embed the parameters in 'src', or use webview.InvokeScriptAsync(). They seem work. But I guess if there is a better way to do this.
If you need the parameters to be available as the page is being loaded, the passing the values as a query string is the simplest option.
Otherwise:
Use invokeScriptAsync (reference) to call a function within the target document after the load has completed. While it delays the set longer than the query string, it's efficient and allows you to keep executing code and adjusting behavior long after the page has loaded. If you can't use the query string for some reason, I'd suggest this.
If the web application has a way to preload the values you need and store them in a Session, it may work, but requires more planning and careful timing.

How to link a google apps script in a google site

I'm creating a google site for my company and I'm utilizing google apps scripts to do a little extra on the site. I would really like to link a script to a drop-down menu that I made. However, I can't figure out how to link the script. I know how to link a script just as a google gadget and as a stand alone link, but I would really like to have the script run when I click on an item from my drop-down menu.
For security reasons, Google don't let you put javascript in Google Sites.
They provide Apps Scripts instead, but as they work on an isolated world (on the server rather than the browser), its very tricky and has its ways.
Because its very different to standard page's javascript, you have to rethink your goal in terms of what Apps Scripts lets you do.
Google Apps Scripts lets you build an User Interface (using its yet experimental UI API) that can be visualized as a standalone script in a full page or inserted in a iframe in Sites. This means you won't have a dropdown menu overlaping your site: you need an static space to visualize your script's UI.
There is another more primitive way to "embed" your scripts commands in your site: use links. A link that fires a script, even with your own parameters, only to run de command, but without any UI. You can make a menu with options, each of them fires a script. But I'm not talking about dropdown menu.
About Google Apps Scripts User Interfaces
https://developers.google.com/apps-script/guide_user_interfaces
https://developers.google.com/apps-script/guide_gui_builder
https://developers.google.com/apps-script/service_ui
Not sure what you mean by "link the script", do you have code someplace else? By "link" it sounds like you mean to "Call" the code, with an event handler. I'll show you how to call a function with a ServerHandler triggered by either a GUI ListBox Change event or from a Button Click event.
In Google Apps Scrips (GAS) there are three methods to do GUI.
HTML Service - Much like plain HTML, you could insert HTML form and input tags.
UI Service - Much like java (as far as layout managers), see below.
GUI Builder - I suggest doing it manually first to better understand layout.
In Google Sites you can add most HTML directly without a script. The UI Service and GUI Builder will generate HTML form tags for you, and since there's rarely any reason to insert GUI elements unless you are executing some code you probably want to start with using these.
Here is a Drop-Down list examplewith some changes to show how a handler function can be called from multiple UI elements (which they call Widgets sometimes) and how to use the parameter:
function doGet(e) { // use doGet() & UiApp to make a canvas.
var app = UiApp.createApplication();
var doEvent = app.createServerHandler('doEvent').setId('doEvent');
var myList = app.createListBox().setId('myList').setName('myList');
myList.addItem('one'); // add items, I use single quote strings.
myList.addItem('two').addItem('three') // I know it looks weird.
// Scripts let you do this, by returning self for your convenience.
.addChangeHandler(
app.createServerHandler('doEvent')
);
app.add(myList); // Add element to GUI.
doEvent.addCallbackElement(myList); // Add to Event Handler.
app.add(app.createButton('Click Me').setId('myButton')
.addClickHandler(doEvent));
return app;
} // Simple DropDown by Jason K.
function doEvent(e) { // use split() if isMultipleSelect is true
var app = UiApp.getActiveApplication();
app.add(app.createLabel(
'List Value is ' + e.parameter.myList
+ ' from ' + e.parameter.source));
return app;
}
As far as troubleshooting, remember to add each element with app.add() and return app; at the end of doGet and each handler function.
Handlers execute a function like JavaScript onClick() or onChange() functions, most UI are not useful without handlers. ClientHandler are more efficient but ServerHandler do more, start with ServerHandlers and any simple functions can be converted to ClientHandlers for better performance. You can choose to space out your handlers or cram it all into one line-of-code, really a matter of personal preference however do assign it to a variable if you plan to use it for more than one GUI object. You may want to look up the different layout managers to make more fancy looking applications, or just use the GUI Builder. Also there use to be other create functions like app.createServerClickHandler() but I understand those were useless and are now deprecated so ignore any other references you find like that, however we do still use addChangeHandler() and addClickHandler() to the GUI elements themselves.
The setName() seems to be silly, it is only needed to set the parameter name (I hope they change that) so for now I suggest just setting it the same as the element id. I also made the Handler's variable name = its id = the event function name just to illustrate how they are all related.

Firefox abort content.location load

I'm developing a firefox extension. Inside my extension I use:
content.location.assign(url)
Depending on the users input content.location.assign(url) gets called again after a short time. It seems like my 2nd assign gets ignored. I'm looking for a way to abort the in process request to push trough the current one.
If I'm not wrong, try using either of this methods:-
reload(forceget)
Reload the document from the current URL. forceget is a boolean, which, when it is true, causes the page to always be reloaded from the server. If it is false or not specified, the browser may reload the page from its cache.
replace(url)
Replace the current document with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session history, meaning the user won't be able to use the Back button to navigate to it.
You shouldn't use content.location to load a new page into the browser; instead use loadURI(url[, referrer[, postData[, allowThirdPartyFixup]]]) to load a page and BrowserStop() to cancel a load.

Resources