How to load local resources? - ibm-mobilefirst

How can I access the resources (CSS, JS and images stored in the project folders) from Worklight?
For example is there an absolute path (a Worklight URL) that points to local internal Worklight resources? Or is maybe another way to load resources from filesystem?
(The reason I'm trying to load resources from local is to speed up the page loading)

Edit: from discussion in the comments it sounds like only looking at the filesystem in the rooted device should suffice.
Edit 2: If what you are looking for is the fastest option to load resources, you shouldn't load them remotely to begin with. Put the index.html in the device. You can't both use Portal to load content remotely, and expect fast loading time. By definition, by loading content remotely, you Will experience possible slowdowns.
Worklight does not supply this path.
Theoretically, you may be able to access the application's sandbox (and thus the web resources) by using the Cordova File API.
You can get a reference to the device's filesystem:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
From there you could access the application's sandbox and find the desired file(s). Since you are the one putting the resources in the app, you should know where you've placed it.
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", null, gotFileEntry, fail);
}
To experiment and find out the paths to the content, you can root your device and then via Eclipse you could traverse the file system. This way you should be able to find the path to the file you've placed.

The only way I managed to access local fiiles in Worklight running an Android environment is using a XMLHttpRequest:
//Works only on Android
function prendiCaricaRisorsaWorklight(percorsoPiuNomeFile) {
var xmlhttp = new XMLHttpRequest();
var risposta = "";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4
&& (xmlhttp.status == 200 || xmlhttp.status == 0)) {
risposta = xmlhttp.responseText;
alert(risposta);
}
}
xmlhttp.open("GET", "file:///android_asset/www/default/"
+ percorsoPiuNomeFile, true);
xmlhttp.send(null);
}
Usage example:
prendiCaricaRisorsaWorklight("css/cssInterno.css");
prendiCaricaRisorsaWorklight("js/jsInterno.js");
This shows on Android an alert with the file content.

Related

Workstation hosted vscode extension not processing message from remote hosted extension

QV https://github.com/microsoft/vscode-remote-release/issues/7736
I have two extensions. One of them is of uiKind workspace and may run locally or remotely depending on the workspace, and the other is of uiKind ui and always runs locally.
The ui extension is responsible for spawning a browser on the user's workstation to load a URI provided by the argument of a command print.launchBrowser that it registers using vscode.commands.registerCommand
The workspace extension uses vscode.commands.executeCommand to invoke print.launchBrowser.
The point of this arrangement is to allow the browser to be launched on the workstation irrespective of whether the extension host is local or remote.
This should work. The following documentation explicitly says it works: https://code.visualstudio.com/api/advanced-topics/remote-extensions#communicating-between-extensions-using-commands
However, when I test it works only when both extensions run on the workstation.
Before anyone tells me to use vscode.env.openExternal(Uri) I am aware of this and am using it to launch the default browser, but this is no use for launching a non-default browser. Many of my users exploit the support for an alternate browser to use Chrome for printing while using a less invasive alternative as their daily drive.
What could cause this to fail? Here's the abovementioned documentation:
Some extensions return APIs as a part of their activation that are intended for use by other extensions (via vscode.extension.getExtension(extensionName).exports). While these will work if all extensions involved are on the same side (either all UI Extensions or all Workspace Extensions), these will not work between UI and Workspace Extensions.
Fortunately, VS Code automatically routes any executed commands to the correct extension regardless of its location. You can freely invoke any command (including those provided by other extensions) without worrying about impacts.
That's not ambiguous.
Since the code for the browser agent is very short I present it in its entirety.
import * as vscode from 'vscode';
import * as child_process from "child_process";
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand("print.launchBrowser", url => {
const browserPath = vscode.workspace.getConfiguration("print").browserPath;
child_process.exec(`${escapePath(browserPath)} ${url}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
if (error || stderr) {
const err = error ? error.message : stderr;
if (!err.startsWith("[")) {
vscode.window.showErrorMessage(err);
}
}
});
}));
}
function escapePath(path: string) {
switch (process.platform) {
case "win32":
return path.includes('"') || !path.includes(" ") ? path : `"${path}"`;
default:
return path.replace(/ /g, "\\ ");
}
}
Code to call it is straightforward. Any extension containing the following should open a browser window and load the bing.com default page, although if you want to use the agent above you'll need to either supply the print.browserPath setting with a value containing the workstation path to a browser or put in such a path as a literal for testing purposes.
There aren't any tests for things like whether browserPath has a value that resolves to a file. That's all in the calling extension, which is designed to use the agent only when it runs in a remote workspace. The agent is essentially nothing but a platform independent remote procedure call.
vscode.commands.executeCommand("print.launchBrowser", "https://bing.com");
All this has been tested and failed on two separate computers and also with VS Code Insiders 1.75.0, which also resolves the question of whether I have a borked VS Code installation.

PouchDB using remoteDB and not local DB instance by default in online mode not not in offline mode

I have attachments saved in a CouchDB database server-side that I want to replicate on a client-side app using PouchDB.
In my app.js file where I handle my application logic, this is at the top:
import PouchDB from 'pouchdb'
var remoteDB = new PouchDB('http://dev04:5984/documentation')
var db = new PouchDB('documentation')
remoteDB.replicate.to(db).on('complete', function () {
// yay, we're done!
}).on('error', function (err) {
// boo, something went wrong!
});
When I turn off access to port 5984 in my firewall, my file can no longer be retrieved and I lose access to my index.html file.
What I am expecting is for all contents of the database 'documentaion' to be copied to my local browser storage -- including pdfs and such -- so that when I turn off port 5984 and then hit refresh, I should still have access to the contents. What am I doing wrong? (see edit -- I figured out that the db is actually replicating, but the local instance isn't being preferred)
EDIT:
I've determined that the database is actually being replicated, but the local storage is only 'preferred' when the browser is in offline mode. So when I refresh while in online mode, with port 5984 blocked, the page is not found. But when I do the same in offline mode (once the contents have been cached already, of course), then the contents can be retrieved.
It would not be an ideal solution to ask my users to always work in offline mode. Is there some way to make the local PouchDB instance the default, even in online mode?
I write to the local db first and "sync" that to a remote db if it's available.
And I use app.cache to provide offline functionality and configure the app to run "offline first".
I read last week that Apple has finally implemented Service Workers in Safari so I'll be looking into implementing that as well now.

Wiki Parsoid error - cannot connect to Parsoid Server

I'm trying to set Parsoid extension and Visual Editor on my wiki page. It is NOT on my localhost. Those who will use the Visual Editor must log in, but the content of the wiki can be read without logging in.
The address is http://contractor.bg/wikimedia/index.php?title=Main_Page
I downloaded the Parsoid extension (in the extension files there is no settings.js file, so I created it according to an example).
My settings are:
in the LocalSettings.php file:
require_once "$IP/extensions/VisualEditor/VisualEditor.php";
$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgHiddenPrefs[] = 'visualeditor-enable';
wfLoadExtension( 'Parsoid' );
$wgVisualEditorParsoidURL = 'http://contractor.bg:2083';
$wgVisualEditorParsoidPrefix = 'wikimedia';
//$wgSessionsInObjectCache = true;
//$wgVisualEditorParsoidForwardCookies = true;
//$wgVisualEditorParsoidTimeout = 120;
I tried with to uncomment the last lines, but it still does not work.
In the settings.js file:
parsoidConfig.setMwApi( 'wikimedia', { uri: 'http://contractor.bg/wikimedia/api.php' } ); // I also tried setting an interwiki value, I am not quite sure what is the difference)
parsoidConfig.serverPort = 2083;
parsoidConfig.serverInterface = 'contractor.bg';
parsoidConfig.strictSSL = false;
parsoidConfig.allowCORS = 'contractor.bg/wikimedia'; // I also tried only contractor.bg)
At the moment when I try to Edit a page with the Visual Editor, I receive an error:
Error loading data from server: 401: parsoidserver-http: HTTP 401. Would you like to retry?
Parsoid is not a MediaWiki extension (well, there was an extension with this name as a support mechanism for the actual Parsoid, but it was never standalone and is no longer required). It is an external service.
You need to actually start the Parsoid service by running node bin/server.js from the Parsoid directory. Ensure it is actually running on the port you specify in the VisualEditor config (2083) - it looks like you have something else there.

MobileFirst JavaScript adapter load local config file

I am creating multiple applications which works the same. For every application I use an adapter which contains the same procedures, but perform the request to a different back end (same host, only different path).
The thing I would like is to add a configuration file (json / xml) to the adapters which I can load and fetch some information from such as the path so I know which back end I need to call. The configuration is now in top of the file, but in the future it would be lovely to be able to update the adapter without changing the configuration afterwards.
Is there a way to load a second file located in the same directory (as where the adapter xml and implementation file are)? I tried using XMLHttpRequest, but this doesn't work as it is unavailable. The code I tried, but couldn't test as the fifth line already breaks.
var config = null;
function loadConfiguration() {
var loader = new XMLHttpRequest();
loader.overrideMimeType('application/json');
loader.open('GET', 'config.json', false);
loader.onreadystatechange = function () {
// Only for async calls.
config = loader.responseText;
};
config = loader.send();
}
If there is a better way, I would love to hear it! We upgraded to MFPF 7.0 if there are any new possibilities.
You cannot do this with JavaScript adapters, however in MFPF 7.0 there is a new type of adapters: Java adapters. Using Java adapters you can achieve this.
The following blog post explains how you can provide a single adapter that will allow you to point to different hosts or differents paths in the same host, etc...
See here: Changing the adapter host at runtime

MVC 4: Durandal bundling cache

My site is built on a WebAPI back end...
the issues occurs on deployment, as my Uri wasn't formatted correctly due to our IIS deployment/site structure
WRONG
http://itil.mysite.com/api/Building
RIGHT
http://itil.mysite.com/TestSite/api/building
So I modified my http helper to include a baseUri
like so
define(function () {
var baseUri = window.AppPath;
return {
baseUri: baseUri,
defaultJSONPCallbackParam: 'callback',
get: function (url, query) {
return $.ajax(baseUri + url, { data: query });
},
...
});
And on my Index.cshtml
added the following to get the set the root/baseUri path:
var AppPath = '#string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"))';
console.log('AppPath: '+AppPath);
The baseUri path is correct when I log it to the console from the Index.cshtml: EG.
AppPath: http://itil.mysite.com/TestSite/
But when I do the actual api call (from my deployed instance), it still uses the old Uri..
http.get('api/building').done(viewInit);
STILL WRONG
http://itil.mysite.com/api/building
My next thought was that the files must be cached somehow, so I tried the following:
Restarted IIS numerous times,
Deleted and redeployed files
Disabled Caching in chrome,
Disabled .js caching in IIS (usermode & kernel
mode),
Restarted my PC
Modified the ScriptBundle to try and force it
to (for the lack of a better word) go out of sync, then added my
code back
The code works when i use my Visual Studio dev server, but I'm getting the
same issue on my local IIS & Alpha test site... with no luck.
How the hell do i clear the cache on a deployed site :/ This is getting to the point where things seems to be a bit ridiculous. Either I'm losing it, or the "big guy" hates me.
Sigh.. Second time I've been caught out by this. I thought my issue was MVC related, its was Durandal deployment related :P
Note to everyone reading this.
Once you deploy a Durandal project & if you modify ANY of the existing javascript files or main.js. Remember to run optimizer.exe.
...\App\durandal\amd\optimizer.exe