Phonegap: InAppBrowser insertCSS file - css

I'm trying to create an app that loads a website and then adds some custom CSS to adjust it to a mobile device.
I'm using window.open to load the page successfully, and I have a callback on loadstop where I'm calling browser.insertCSS, this is where the problem is.
If I do something like this:
browser.insertCSS({code:"body{background-color:red;}");
The style is applied correctly. However if I do this:
browser.insertCSS({file:"mobile-style.css");
And add the same CSS to the file, it doesn't get loaded
I have tried different paths (putting the file in the www folder, in the css folder, in the same folder as the JS file, and referencing it with "./mobile-style.css", "mobile-style.css", "/www/mobile-style.css", "/mobile-style.css" but none of them seem to load the file correctly.
I saw another post What should file paths fed to insertCSS() be relative to? where this same question was asked, but there is no accepted answer (I have tried the suggestion there and it doesn't work).
Any help would be greatly appreciated.
Thanks
Will

you have to wait until your inAppBrowser page loading finishes.
You must add an event listener:
var inApp = window.open('mypage.html', '_blank', 'location=no');
inApp.addEventListener('loadstop', function(){
inApp.insertCSS({
file: 'inAppStyle.css'
},onSuccess);
});
EDITED
Use this path for your android projects file:///android_asset/{your folder}
INFO: https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#android-file-system-layout

I couldn't find the right local path. Instead, I just uploaded the css file to the web and provided a regular URL
file: 'http://mywebsite.com/path-if-needed/my.css'
Not ideal to have an external dependency, but not a big deal since InAppBrowser itself requires internet access.

I probably know why it won't work, it is because your path isn't right, this css file should not put in www folder, neither the cordova project folder, u should put it into the server, for example, if ur browser is to visit http://192.168.1.1/admin, then the cordova only fetch this file when the browser is under the 192.168.1.1/admin, it fetch the file under the server directory.I don't know if u use any debug tool , if u use one, it's easy to find out what went wrong, ur console will log the error which path it fetch the css file and didn't get it.

If you want to add an external CSS file stored locally in the APP's sandbox and not around in the Internet, this is the only way, that is, you get the external file, you store it into a string variable, and then you insert such code into the Browser.
var inAppBrowserRef = cordova.InAppBrowser.open(url, "_blank", "location=no");
//when load stops call loadedCallbackFunction
inAppBrowserRef.addEventListener('loadstop', loadedCallbackFunction);
function loadedCallbackFunction() {
console.log("InAppBrowser Window loaded");
$.ajax({
type: "GET",
url: cordova.file.applicationDirectory + "www/css/myExternalCSS.css",
dataType: "text",
success: function (CSScode) {
inAppBrowserRef.insertCSS(
{ code: JScode},
function(){
console.log("CSS code Inserted Succesfully into inApp Browser Window");
});
},
error: function () {
console.error("Ajax Error");
}
});
}
You need the cordova-plugin-inappbrowser

Related

Loading local file inside an iframe in Electron

I've tried different approaches but all are problematic.
So first of all I was using webview, but as per electron documentation, this tag is undergoing major architectural changes and it's recommended to use iframe or other alternatives. Furthermore, the webview tag gives me a warning while used alongside VueJS that the component is not registered. I understand this component doesn't exist within HTML standards and is something specific to electron, so I am not sure how to tell Vue to ignore or recognize it in the use case of an electron app.
Coming to the iframe problem, approach one of loading the file directly via src, gives me the obvious error Not allowed to load local resource:. Turning off webSecurity though allows the file to load but I read it's not recommended to turn it off. I am not sure if there are specific use case where it's safe to turn it off or shouldn't be at all.
I decided to try via file protocol as I already have it in place. The protocol code:
protocol.registerFileProtocol('downloads', (request, callback) => {
const url = request.url.substring('downloads:///'.length)
const location = path.normalize(paths.downloads(url))
callback({ path: location })
})
Though when I load the file this way, the renderer process crash without errors. Is there something in addition to the above which would help loading local files via iframe?
Edit 1
My use case is the following: I have a typical entry point to an index.html which contains code for a VueJS app.
if (app.isPackaged) {
window.loadFile(join(__dirname, '../renderer/index.html'))
} else {
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin
const url = `http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`
window.loadURL(url)
window.webContents.openDevTools()
}
Inside that VueJS app, I require to list html files from a directory. I am able to achieve so via webview but I have tried to move away from it for the reason mentioned above. I tried using iframe but encountered issues as well. If there's a setting that doesn't turn off all security and allows me to load the file via iframe, that would be ideal.
This is kind of the reverse of this question where they're using an iframe, running into the "not allowed to load local resource" and being told to use a <webview> instead.
The <webview> docs list BrowserView as another alternative which is what I would recommend here. That should be much easier to work with than an iframe.
const { app, BrowserView, BrowserWindow } = require('electron')
app.whenReady().then(() => {
const win = new BrowserWindow()
const view = new BrowserView()
win.setBrowserView(view)
view.setBounds({ x: 0, y: 0, width: 300, height: 300 })
view.webContents.loadFile('<yourFile>')
})
Even though it is not recommended to use webview tag, I decided to go forward as it's the only thing that works for me. The only issue then was this error where Vue does not recognize the tag. To work around that error/warning, I had to update my vite.js config:
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === 'webview'
}
}
}),
// ...

ApostropheCMS 2 CSS Issue

I've one apostrophe CMS 2 project where I am trying to make changes in the css file which resides in "lib\modules\apostrophe-assets\public\css\site.css" and there is another minify css file generated in public\css\master-anon-cl2eiqkd30003wwb6kl1553jg.less.
So whatever i make changes in minify files it reflects in front side and if I do that changes in 'lib\modules\apostrophe-assets\public\css\site.css' it didn't reflect.
Then I've fired below command to minify this files node app apostrophe:generation
Ref Link # : https://v2.docs.apostrophecms.org/devops/deployment/deployment.html#always-minify-before-startup
After firing this command than new scripts & styles are created but however changes are not getting reflected in the test server and website styles gets messed up.
Could you please suggest any solution
Hi I don't know if this is going to help you, but try to add this peace of code to your module, widget
enter code here
construct: function(self, options){
var superPushAssets = self.pushAssets;
self.pushAssets = function(){
superPushAssets();
self.pushAsset('stylesheet', 'style-name', {when: 'always'};
};
};

Route paramters cause CSS not to load while using Node.js and Express

I'm building a simple website using Node.js, Express and the EJS template engine and I'm having trouble getting my external CSS files to load on the routes that have route parameters. My code looks like this:
const express = require("express");
const app = express();
var AWS = require('aws-sdk');
var uuid = require('uuid');
var request = require('request');
var Amplify = require('aws-amplify');
const { info } = require("console");
app.use(express.static("public"));
app.set("view engine", "ejs");
app.get("/Test1/", function(req, res){
res.render("Test1.ejs");
});
app.get("/Test2/:route", function(req, res){
res.render("Test2.ejs")
});
Test1.ejs and Test2.ejs are exact duplicates of each other, one being copy pasted from the other.
I'm able to to see the CSS file loading properly on Test1 but on Test2 express is sending the HTML of Test2.ejs in place of the actual CSS file. This is without reloading or changing anything. I would be less confused if the CSS just wasn't loading properly on any of my routes, as that would indicate some problem with how I'm using express, but I can't figure out how it can be working properly on all my other routes and fail whenever a route parameter is used. I'm also tried actually using the route parameter e.g.
app.get("/Test2/:route", function(req, res){
const routeParam = req.params.route;
res.render("Test2.ejs", {
routeParam: routeParam
});
});`
I also displayed routeParam in the page to make sure that was working, and it does, except the page is still getting the HTML of the page in place of the proper CSS file, causing it to be poorly formatted.
I'd appreciate any help on this, thank you
Thanks for looking into this CoderFF, you helped me figure out how to get it to work. It look like the problem was that my css file was directly inside the public folder, as opposed to in a subdirectory within it. The html has to be like this:
<link rel="stylesheet" type="text/css" href="/css/customStyle.css" />
it has to include that leading '/' in the href tag. I don't know how it was working for me before without that on routes without route parameters, but it was. The same seems to apply for images in an /images/ folder within the public folder.
I can't really reproduce this. What I'm doing is:
Placed my CSS in public/css/all.css. File contains only one line: html {background-color: #aaaaaa} so I can tell it's loaded
Place two templates into views/Test1.ejs and views/Test2.ejs and put the same contents in them: <html><head><link rel="stylesheet" type="text/css" href="/css/all.css"/></head><body></body></html>
And it works perfectly.
I suppose that you've created a folder Test2 inside of your public/ folder, in which you placed your CSS. In that case, your path to the CSS is /Test2/some.css matches your second route and instead of getting a CSS file, you get an HTML from the route.
In that case, moving your CSS files will help.

Unable to load an image in sub folder present in the working directory- Google maps marker icon

A simple issue but unable to find a solution.
I have some image files that I placed in a subfolder called icons in my working directory in my ASP.NET website. I want to set an image during initialization to the markers on my Google map. But this isn't working. I have tried-
var marker= new google.maps.Marker({icon:'E:\cdeez\Sites\googletest 5\icons\busballon.png', position:pos,map:map});
It gives an error:
Not allowed to load local resource: file:///E:/cdeezSitesgoogletest%205icons%08usballon.png
However there is no problem if I place the image in the working directory. I guess giving the absolute path is not the right way too. So what is the right way in the above case.(Just a reminder- the above code will be in the aspx file).
According to the MarkerOptions docs, the icon should be a URL. However local files (embedded with file:///) tend to be ignored by browsers if the website is served over http - and I think that is what is happening in your case.
I would suggest to try out the following steps:
try using a relative path, e.g icon: "/icons/busballon.png"
try using a http path to your file, e.g. icon: "http://yoursite.com/icons/busballon.png"

How can I apply GA download tracking with Sitecore?

I'm posting this question to Stackflow b/c after doing much research into an answer to this very question online, I did not come across a straight forward answer and had to do my own sleuthwork to resolve this.
Basically, Sitecore uses a handler file .ASHX for all files uploaded to the Media Library. Since the 3rd party GA tracking tool I was using (entourage.js or gatags.js) does not recognize .ashx as a whitelisted download file, it was not adding the appropriate GA tracking syntax to the GA pixel tracker (__utm.gif).
So the solution turns out to be simple but sadly, not retroactive, meaning all files previously uploaded to the Media Library in the Sitecore content tree will continue to use the ashx extension unless you reupload the image. In your web.config file, search for the "Media.RequestExtension" setting. If you change the value associated with this setting from "ashx" to a blank string, this will force Sitecore to use the originalextension of the file and image in the Sitecore Media Library.
Aside from interfering with GA analytics, this method of turning every downloadable file extension into an ashx file is poor SEO practice. AND, Sitecore will not point you in the right direction of getting around this other than a round-about way (google Sitecore dynamic linking and configuration) because they want you to use their Sitecore OMS download tracking capability. And that's it! Two days of research led me to this conclusion.
So the solution turns out to be simple but sadly, not retroactive,
meaning all files previously uploaded to the Media Library in the
Sitecore content tree will continue to use the ashx extension unless
you reupload the image.
Not sure where you got this information, but it's incorrect. You can blank out the Media.RequestExtension setting and all existing files will use their original extension. In IIS7 Integrated Mode, you should be able to make this change without having to make other server configuration changes.
Edit: More Info
If you analyze Sitecore.Configuration.Settings.Media.RequestExtension (the API equivalent to this settings) in a decompiler, you can see that it's only used by the MediaProvider when constructing the Media URL. Sitecore should remember the original extension of the media and can serve it with its original URL, regardless of what this setting was when it was uploaded. That's my experience, anyway, and it seems to be validated by looking into Sitecore.Kernel.
You could use this script to track download events via Google Analytics.
if (typeof jQuery != 'undefined') {
jQuery(document).ready(function($) {
var filetypes = /\.(zip|pdf|doc*|xls*|ppt*|jpg|ashx)$/i;
var baseHref = '';
if (jQuery('base').attr('href') != undefined) baseHref = jQuery('base').attr('href');
jQuery('a').each(function() {
var href = jQuery(this).attr('href');
if (href) {
if (href.indexOf('?') != '-1') {
href = href.substring(0, href.indexOf('?'));
}
if (href.match(filetypes)) {
jQuery(this).click(function() {
var extension = String((/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined);
var filePath = String(href);
_gaq.push(['_trackEvent', 'Download', extension, filePath]);
if (jQuery(this).attr('target') != undefined && jQuery(this).attr('target').toLowerCase() != '_blank') {
setTimeout(function() {
location.href = baseHref + href;
}, 200);
return false;
}
});
}
}
});
});
}
Just add in the required file types here at this line -
var filetypes = /.(zip|pdf|doc*|xls*|ppt*|jpg|ashx)$/i;
Having done a quick google for gatags.js, I can see that you can add an extension to the whitelist on line 24:
var isDoc = path.match(/\.(?:doc|eps|jpg|png|svg|xls|ppt|pdf|xls|zip|txt|vsd|vxd|js|css|rar|exe|wma|mov|avi|wmv|mp3)($|\&|\?)/);
Change it to:
var isDoc = path.match(/\.(?:ashx|doc|eps|jpg|png|svg|xls|ppt|pdf|xls|zip|txt|vsd|vxd|js|css|rar|exe|wma|mov|avi|wmv|mp3)($|\&|\?)/);
Alternatively, you could attach the Google Analytics _trackEvent yourself with a dom selector and a click event.
Either way, I think OMS can track media library files regardless of extension - removing the default ashx extension doesn't stop the file being handled by Sitecore.

Resources