How to include additional CSS files in Aurelia? - css

Ihave a app that opens a new window with content. I need special CSS for that window.
Code for opening the window is this:
var Printwindow = window.open("","","width=360,height=188");
var cssFile = Printwindow.document.createElement("link");
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "../../content/label.css";
Printwindow.document.write("<head>" + cssFile.outerHTML + "</head><body onload='window.print();'>" + this.label.innerHTML + "</body>");
Printwindow.document.close();
Printwindow.focus();
the label.css is there when i just run it in localhost. But when i build it and eploy it to server it is missing. How can i include this label.css in the bundle so that it can find it?

If you are using webpack, you should reference the file so webpack finds it:
cssFile.href = PLATFORM.moduleName("../../content/label.css");
and do the import of PLATFORM:
import {PLATFORM} from 'aurelia-pal';
Hope it helps.

Personally, I would recommend that you create a component and compose that within a dialog or new window. This will allow you to avoid building your presentation layer within JS. If you created a custom-component, you could do the following:
<template>
<require from="label.css"></require>
{Content Here}
</template>
You could then compose this into a dialog.
Alternatively, if you're unable to make structural changes, then you should import PLATFORM from aurelia-pal and use it as such:
import {PLATFORM} from 'aurelia-pal';
// .. other code here ..
cssFile.href = PLATFORM.moduleName("../../content/label.css");
If you are still having issues, then it may be because you need to resolve your production server's base URL.

Related

Serve css files dynamically in raw node.js

I can servre css files when the browser requests for it, which is like
var pathname = url.parse(req.url, true);
if(pathname=="style.css"){
//read the css file and write in the response
}
but using this approach i will have to write a router for each css and js file I use. Is there any way to do them dynamically. I have figured out a way which works but seems to be vaulnarable.
var reqArray = pathname.split("/");
if(req.Array[reqArray.length -1].indexOf(".css") !=-1 && fs.existsSync(pathname)){
fs.readFile("./"+pathname, function(err,data){
//server the file
}
}
is it okay, or there is any better suggestion. Please don't tell me to use express or any toher framework.

Vue + Webpack + Meteor Client Side

I want integrate meteor-client-side from NPM in a vue.js Webpack project.
The project is generated with vueCli.
This is my main.js file:
import Vue from 'vue'
import App from './App'
require('meteor-client-side')
console.log(Meteor.status())
/* eslint-disable no-new */
new Vue({
el: 'body',
components: { App }
})
With console.log i get a eslint error 'Meteor is not defined', but when i try Meteor.status() on the browser console it works fine.
What i doing wrong?
I don't want use vue in meteor, i need meteor-client-side in this non meteor project.
Many thanks for help
Try
var Meteor = require('meteor-client-side');
console.log(Meteor.status())
If you want to use a node module in the code you need to assign it to a variable, like var $ = require('jquery');. But if the JS just does things on its own and you don't need a reference to it, you can just require it, so like:
var $ = var jQuery = require('jquery'); //sets $ to jquery
require('bootstrap'); //just extends jquery, no need to save reference

jsdom does not fetch scripts on local file system

This is how i construct it:
var fs = require("fs");
var jsdom = require("jsdom");
var htmlSource = fs.readFileSync("./test.html", "utf8");
var doc = jsdom.jsdom(htmlSource, {
features: {
FetchExternalResources : ['script'],
ProcessExternalResources : ['script'],
MutationEvents : '2.0'
},
parsingMode: "auto",
created: function (error, window) {
console.log(window.b); // always undefined
}
});
jsdom.jQueryify(doc.defaultView, 'https://code.jquery.com/jquery-2.1.3.min.js', function() {
console.log( doc.defaultView.b ); // undefined with local jquery in html
});
the html:
<!DOCTYPE HTML>
<html>
<head></head>
<body>
<script src="./js/lib/vendor/jquery.js"></script>
<!-- <script src="http://code.jquery.com/jquery.js"></script> -->
<script type="text/javascript">
var a = $("body"); // script crashes here
var b = "b";
</script>
</body>
</html>
As soon as i replace the jquery path in the html with a http source it works. The local path is perfectly relative to the working dir of the shell / actual node script. To be honest i don't even know why i need jQueryify, but without it the window never has jQuery and even with it, it still needs the http source inside the html document.
You're not telling jsdom where the base of your website lies. It has no idea how to resolve the (relative) path you give it (and tries to resolve from the default about:blank, which just doesn't work). This also the reason why it works with an absolute (http) URL, it doesn't need to know where to resolve from since it's absolute.
You'll need to provide the url option in your initialization to give it the base url (which should look like file:///path/to/your/file).
jQuerify just inserts a script tag with the path you give it - when you get the reference in the html working, you don't need it.
I found out. I'll mark Sebmasters answer as accepted because it solved one of two problems. The other cause was that I didn't properly wait for the load event, thus the code beyond the external scripts wasn't parsed yet.
What i needed to do was after the jsdom() call add a load listener to doc.defaultView.
The reason it worked when using jQuerify was simply because it created enough of a timeout for the embedded script to load.
I had the same issue when full relative path of the jquery library to the jQueryify function. and I solved this problem by providing the full path instead.
const jsdom = require('node-jsdom')
const jqueryPath = __dirname + '/node_modules/jquery/dist/jquery.js'
window = jsdom.jsdom().parentWindow
jsdom.jQueryify(window, jqueryPath, function() {
window.$('body').append('<div class="testing">Hello World, It works')
console.log(window.$('.testing').text())
})

Load local file through HTML page inside stage webview

I have to show local image file in html through stagewebview.
When I load url of html in flex application, text content displyaed correctly, but it doesn't show a images for that. Any way I can load local file through html in stage web view?
The solution involves copying all your necessary files (html, images, css) to a storage directory, and then call your html in there. The URLs to images and CSS will be relative to that directory.
This code shows how to copy the contents of an entire directory called html into that storage directory, and then load test.html into your StageWebView object.
var source:File = File.applicationDirectory.resolvePath("html/") ;
var destination:File = File.applicationStorageDirectory;
source.copyTo(destination, true);
var initialURL = new File(destination.resolvePath("test.html").nativePath).url;
webView.loadURL( initialURL );
Be aware that you will be responsible for cleaning up that directory though.
You can load a local HTML file using the File Class. So it would be something like this:
var _locaWebFile:File = File.documentsDirectory.resolvePath(pathToHTMLContent);
var _webview:StageWebView = new StageWebView();
_stage.scaleMode = StageScaleMode.NO_SCALE;
_webview.stage = _stage;
_webview.loadURL(_localWebFile.url);
_webview.addEventListener(flash.events.Event.COMPLETE, loadData);
function loadData(e:Event):void
{
_webview.viewPort = new Rectangle(0, 0, _stage.stageWidth, _stage.stageHeight);
}
Also, you might have to make sure your paths to your images are correct.

Looking for CSS parser written in AS3

I need to load and apply CSS at runtime in my Flex app. I know that the adobe docs say that you need to compile the CSS before loading it but I would like to find a work around.
I know that you can set individual styles like this:
cssStyle = new CSSStyleDeclaration();
cssStyle.setStyle("color", "<valid color>);
FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("Button", cssStyle, true);
I was planning on parsing a CSS file and appling each attribute as above.
I was wondering if:
Adobe had a CSS parser library that I could use
Someone else had a CSS parser that I could use
If I write my own CSS parser what I should watch out for
I know that the adobe flex.text.StyleSheet class has a CSS parser but I could not find a way to harness that. (Is there a way to get that source code?)
Edit: This solution does not work. All selectors that are taken out of the parser are converted to lowercase. This may work for your application but it will probably not...
I am leaving this answer here because it may help some people looking for a solution and warn others of the limitations of this method.
Although it was not intended for this it is possible to use the StyleSheet class to parse the CSS. I am currently investigating how robust this is currently but for the most part it appears to be working.
public function extractFromStyleSheet(css:String):void {
// Create a StyleSheet Object
var styleSheet:StyleSheet = new StyleSheet();
styleSheet.parseCSS(css);
// Iterate through the selector objects
var selectorNames:Array = styleSheet.styleNames;
for(var i:int=0; i<selectorNames.length; i++){
// Do something with each selector
trace("Selector: "+selelectorNames[i];
var properties:Object = styleSheet.getStyle(selectorNames[i]);
for (var property:String in properties){
// Do something with each property in the selector
trace("\t"+property+" -> "+properties[property]+"\n");
}
}
}
I had similar problem but more precisely i want the completely avoid the compilation because my application is wrapper by ActiveX used by a custom exe file and i let the software distributor to customize their skin.
In practice we put the <fx:Style> outside the application. To avoid low level parsing on the string we had transformed the Style Sheet in an XML:
<styles>
<namespace name="myNs" value="com.myComponent">
<declaration selector="myNS|Button#myselector:over #mysubselector">
color:#ffffff;
font-size:bold
</declaration>
... other styles
</styles>
Beside the security considerations about let the user know your components you can load the XML and create a CSSStydeclaration.
Splitting and parsing only the selector let you create a series of CSSCondition and CSSSelector to add to your CSSStyleDeclaration. To parse the selector we use a little loop which search "#",":" and "." and split the string mantaining the sequence of the found CSS conditions.
var selectors:Array = [];
// first selector
var conditions:Array = [
new CSSCondition(CSSConditionKind.ID, 'myselector');
new CSSCondition(CSSConditionKind.PSEUDO, 'over');
];
// here you have to find and expand the namespace
ancestor:CSSSelector = new CSSSelector('com.myComponent.Button', conditions);
selectors.push(selector);
// second selector
var conditions:Array = [
new CSSCondition(CSSConditionKind.ID, 'mysubselector');
];
selector:CSSSelector = new CSSSelector('', conditions, ancestor);
selectors.push(selector);
// Empty style declaration
new CSSStyleDeclaration(selectors, styleManager, false);
Then you can parse CSS properties by parseCSS() with the function created by #sixtyfootersdude, but using a fake selector:
var myCSS:String = "#fake " + "{" + cssTextReadedFromXML + "}";
var style:StyleSheet = new StyleSheet();
sheet.parseCSS(myCSS);
// here you have your parsed properties
var list:Object = sheet.getStyle('#fake');
Then you can add the properties to the CSSStyleDeclaration and apply them by the setStyle method and apply the declaration as in your example.
Less or more is how I've tryed to resolve this.

Resources