IFrame, how to share css file - css

I've just joined a project where we are using sap netweaver to generate the website.
Until now people have been working on their DCP individually and therefore I now have 20 DCP to link together and style.
At the root, each DCP is an IView/IFrame.
We currently have 20 css files that makes it hard to maintain and quickly change so I'm looking to use scss to generate 1 css file to make everything work.
That part works fine, however I hit a problem, since each IFrame renders itself, each one loads a css file so I get 20 calls to the my new css file.
Is there a way to share the css file between the parent view and the IFrame, or at least set it so that the css file is downloaded once and the other 19 just use the cached version?
Cheers
Jason

<script type="text/javascript">
$(document).ready(function() {
//pulling all <style></style> css of parent document
if (parent) {
var oHead = document.getElementsByTagName("head")[0];
var arrStyleSheets = parent.document.getElementsByTagName("style");
for (var i = 0; i < arrStyleSheets.length; i++)
oHead.appendChild(arrStyleSheets[i].cloneNode(true));
}
//pulling all external style css(<link href="css.css">) of parent document
$("link[rel=stylesheet]",parent.document).each(function(){
var cssLink = document.createElement("link")
cssLink.href = "http://"+parent.document.domain+$(this).attr("href");
cssLink .rel = "stylesheet";
cssLink .type = "text/css";
document.body.appendChild(cssLink);
});
});
</script>
It will able to inherit the css which is defined in the external style sheet as well as css defined in the tag of parent document.

Related

Adding css global variables using javascript

First of all if you read this question and I did have any misunderstandings of how css works please let me know
I'm trying to add some global variables to my stylesheets and I want to do it with javascript (I thought there may be a way to use global variables without importing a css file containing those variables in each css file I'm creating):
let cssContent = `:root{ --mainColor:"#333";}
First I tried to create a new stylesheet file and put cssContent in there:
var blob = new Blob([cssContent]);
var url = URL.createObjectURL(blob);
var cssElement = document.createElement('link');
cssElement.setAttribute('rel', 'stylesheet');
cssElement.setAttribute('type', 'text/css');
cssElement.setAttribute('href', url);
Then to add this stylesheet to head, first I removed all exsisting stylesheets, add cssElement and then all the other removed stylesheets so the cssElement be the first stylesheet in head element.
var cssElements = Array.from(document.head.getElementsByTagName('link'))
.filter(link => link.getAttribute('rel') == 'stylesheet');
if (cssElements && cssElements.length > 0) {
cssElements.forEach(cssEl => {
document.head.removeChild(cssEl)
});
The behavior of removing and adding stylesheets works fine
But the :root element goes after the defined rule for body and does not apply:
Then I tried to add this variables to each css file instead of creating new one:
for (let index = 0; index < document.styleSheets.length; index++) {
document.styleSheets[index].insertRule(cssContent, 0);
}
Again same thing happened to previous approach, happens here too:
At last I tried to add this variables to each rule, but I couldn't find an approach
Is there any way to do this?
you can use these three:
document.documentElement.style.setProperty("--mainColor", "#333");
Element.setAttribute()
OR
document.documentElement.style.cssText = "--mainColor: #333";
Document.documentElement
OR
document.documentElement.setAttribute("style", "--mainColor: #333");
CSSStyleDeclaration.setProperty()

Html element which ignores all parent css

Im embeding a word document saved as html in my site, but there are conflicts between the generated css and my site’s. What could really help me is having a “scoped” element, which is not effecting or being effected by the site itself. Is there any solution to this problem? Thanks
I personally use classes as wrappers for scoping. Below all of the styles from the word document will be "scoped" to the beginning and ending of the span tag.
/*some css wrapper class*/
.word-document-wrapper
{
}
<span class="word-document-wrapper>
<!--word document here-->
</span>
You can use HtmlSaveOptions class to specify additional options when saving a Word document into the Html, Mhtml or Epub format. For example:
Document doc = new Document("D:\\Temp\\input.docx");
HtmlSaveOptions opts = new HtmlSaveOptions(SaveFormat.Html);
opts.CssStyleSheetType = CssStyleSheetType.Embedded;
opts.ExportImagesAsBase64 = true;
opts.ExportFontsAsBase64 = true;
opts.PrettyFormat = true;
doc.Save("D:\\temp\\18.8.html", opts);
I work with Aspose as Developer Evangelist.

Use a remote stylesheet inside a template tag (with shadow dom)

I am trying to make a semi-resuseable widget but I am running into a problem. I am trying to encapsulate a some CSS code inside a shadow root so that it does not affect the rest of the webpage but this CSS is used across multiple widgets so I am trying to include a remote stylesheet. None of the examples I have found use a remote style sheet and I was wondering if this was possible.
EX:
<template id="templateContent">
<head>
<link rel="stylesheet" href="css/generalStyle1.css">
</head>
<body>
<div class="affectedByGeneralStyle1"></div>
</body>
</template>
script to include template:
<div id="host"></div>
<script>
var importedData = (html_import_element).import.getElementById("templateContent");
var shadow = document.querySelector('#host').createShadowRoot();
var clone = document.importNode(importedData.content, true);
shadow.appendChild(clone);
</script>
I came across the same problem recently. What I ended up doing was using:
<template id="templateContent">
<style> #import "css/generalStyle.css"; </style>
</template>
Additional info: This worked just fine except that now I'm having some cache issues as Chrome does not seem to reload those resources after a hard reload.
Let add to the answer . Now direct tag is supported in shadow dom.
You can directly use
<link rel="stylesheet" href="yourcss1.css">
<link href="yourcss2.css" rel="stylesheet" type="text/css">
Check they has been update by whatwg and W3C
Useful link for using css in shadow dom.
https://w3c.github.io/webcomponents/spec/shadow/#inertness-of-html-elements-in-a-shadow-tree https://github.com/whatwg/html/commit/43c57866c2bbc20dc0deb15a721a28cbaad2140c
https://github.com/w3c/webcomponents/issues/628
Direct css link can be use in shadow dom
Thanks.
I added the stylesheet's link element directly to the shadow root this way:
let link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'whatever.css');
this.shadowRoot.appendChild(link);
It seems to work fine. (I called this from the constructor of the component.)
actually polymer has an internal utility to load css links, i have implemented a javascript function that is using polymer internal css processor,so if you want to add css links at runtime you can use it:
Polymer('my-element', {
ready: function () {
this.importCss("path/myfile.css");
},
importCss: function (path) {
var $shadow = $(this.shadowRoot);
var $head = $("<div></div>");
var $link = $("<link rel='stylesheet' type='text/css'>");
$link.attr("href", path);
$head.append($link);
var head = $head[0];
this.copySheetAttributes = Polymer.api.declaration.styles.copySheetAttributes;
Polymer.api.declaration.styles.convertSheetsToStyles.call(this, head);
var styles = Polymer.api.declaration.styles.findLoadableStyles(head);
if (styles.length) {
var templateUrl = this.baseURI;
Polymer.styleResolver.loadStyles(styles, templateUrl, function () {
var $style = $shadow.find("style");
if ($style.length > 0){
$shadow.find("style").append($head.find("style").html());
}else{
$shadow.append($head.html());
}
});
}
}
});
Note: this code needs jquery to run

bookmarklet css stylesheet inject

I want to insert a css stylesheet with bookmarklet
javascript:(function(){var%20s=document.createElement('link');s.setAttribute('href','http://localhost/~simha/new.css');s.setAttribute('rel','stylesheet');s.setAttribute('type','text/css');document.getElementsByTagName('head')[0].appendChild(s);alert('Stylesheet%20injected!');})();
when deminified
javascript: (function () {
var s = document.createElement('link');
s.setAttribute('href', 'http://localhost/~simha/new.css');
s.setAttribute('rel', 'stylesheet');
s.setAttribute('type', 'text/css');
document.getElementsByTagName('head')[0].appendChild(s);
alert('Stylesheet injected!');
})();
I made this bookmarklet and ran, it added the link element in the head of the html, with the css href also. BUt the css rules in the new.css didnt apply. There are not changes made to the web page.
Nowadays the CSP rules are common on websites, it is better to just write the style in the bookmarklet itself. See a live example here
(function () {
var s = document.createElement('style')
s.innerText = "body { background-color: red }"
document.head.appendChild(s)
})();

How to set the default font in Google Closure Library rich text editor

Google Closure Library editor: demo, documentation.
The editable area is an iframe. How can I set the default font of the editable area? Now it is the default font of the browser. I prefer not to put a font tag around the content in the editable area**. That way, I can change the font of my website in the future, without the need to modify every HTML-content written in the editor.
** What I mean by that is something like this:
<font size="2" face="georgia, serif"><b>content</b></font>
I would prefer just this:
<b>content</b>
... and then style the editable area of the editor with the georgia font using CSS. That way, the HTML-content (produced by the editor) in my database wouldn't contain a hard-coded font, so I could change the font in the future.
Edit: maybe I should use a SeamlessField instead of a Field for the editable area?
Once you call makeEditable() on the goog.editor.Field, which creates the iFrame you referenced, the Field fires an event of type goog.editor.Field.EventType.LOAD. If you listen to that event, you can pull out the iFrame and toss in a link element to a CSS stylesheet so you can easily modify the content in your editor.
Here's the equivalent of one of my listeners that should get you on the right track. (I didn't check if the goog.editor.Field was the target of the event, but I assume it is).
some.namespace.Page.prototype.onEditorLoad_ = function(event) {
var editor = /** #type {goog.editor.Field} */ (event.target);
var iFrame = editor.getEditableIframe();
if (iFrame) {
var fieldDomHelper = editor.getEditableDomHelper();
var documentNode =
fieldDomHelper.getFrameContentDocument(iFrame).documentElement;
var head = documentNode.getElementsByTagName(goog.dom.TagName.HEAD)[0];
if (!head) {
head = fieldDomHelper.createDom(goog.dom.TagName.HEAD);
goog.dom.insertChildAt(documentNode, head, 0);
}
fieldDomHelper.appendChild(
head,
fieldDomHelper.createDom(
goog.dom.TagName.LINK,
{ 'href': '/css/myCSS.css', 'rel': 'stylesheet', 'type': 'text/css' }
)
);
}
}
Finally, in that CSS file, you can add whatever styling you want. Such as your font change.

Resources