Cesium: Theming the InfoBox - cesiumjs

I have seen a few examples on Google Groups which demonstrate how to modify the css of the infobox. In this particular example, javascript is used to append a css link to the head of the document:
https://groups.google.com/forum/#!topic/cesium-dev/f0iODd42PeI
var cssLink = frameDocument.createElement("link");
cssLink.href = buildModuleUrl('Path/To/Your/CSS/File.css');
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
viewer.infoBox.frame.contentDocument.head.appendChild(cssLink);
This, however, has not resulted in any changes to the style of my markup.
At best, I have been able to wrap the contents of the infobox by iterating through the entities in the .then function call subsequent to loading a geoJson dataset. When wrapping the contents, I can set style values which are readily apparent in the resulting markup.
var dataSource = Cesium.GeoJsonDataSource.load('../data/mGeoJson.json').then(function(data) {
viewer.dataSources.add(data);
var entities = data.entities.values;
for (var i = 0; i < entities.length; i++)
var entity = entities[i];
if (entity.properties.hasOwnProperty("description")) {
entity.description = '<div style="height: 360px;">' + entity.properties.description
+ '</div>';
}
}
}
This is useful, but does not completely satisfy the requirements of my app.
Could someone provide additional insight into overriding the theme of the infobox, without having to iterate over entities to modify the value of their description properties?

The original solution here wasn't working, because the infoBox is an iframe that has not yet asynchronously loaded when you were trying to modify it.
Instead, you can add an load listener to the iframe, like this:
var viewer = new Cesium.Viewer('cesiumContainer');
var frame = viewer.infoBox.frame;
frame.addEventListener('load', function () {
var cssLink = frame.contentDocument.createElement('link');
cssLink.href = Cesium.buildModuleUrl('Path/To/Your/CSS/File.css');
cssLink.rel = 'stylesheet';
cssLink.type = 'text/css';
frame.contentDocument.head.appendChild(cssLink);
}, false);
This waits for the iframe to become ready to receive the modification, and then applies it.

For what it's worth, I've found success in modifying the theme of the infobox by simply importing my css files in the head of the document. I'm not sure why I wasn't able to modify it directly with stylesheets, as it wasn't previously affecting the infobox's appearance, and this issue was mirrored in the posts that I found in the cesium-dev Google Group. Regardless, it seems to be working just fine now.

Related

TableRow cells Collection set attribute

I'm looping through a table in the form of table.rows.length and inside it rows.cells.length and when a certain cell meets a certain criteria then I would like to set an attribute to that html of that cell.
I know you can change the innerHTMl like
var x = document.getElementById("myTable").rows[0].cells;
x[0].innerHTML = "NEW CONTENT";
so I thought the attr would be like
x[0].attr = ('name', 'value');
But no such luck.
could someone please point me to the right direction?
If there are any resources you can recommend that give a full list of all the options you can add to a cell this way that would be great!
Since you're operating with HTML nodes directly - you're dealing with HTMLElement objects that are, in their turn, inherited from generic Element.
As you can see from documentation - you can reach attributes through Element.attributes map, each of them are Attr object with name and value properties.
So correct way will be to use:
x[0].setAttribute('name', 'value');
Working with jQuery and es6 syntax you could use the map function:
var xtr = $('#mytable tr');
xtr.map(itr => {
xtd = $(itr).children('td');
xtd.map(itd => {
$(itd).attr('key', 'value');
});
});
If thats confusing you can work with the for loop the old way:
var xtr = $('#mytable tr');
for(i in xtr){
xtd = $(xtr[i]).children('td');
for(j in xtd){
$(xtd[j]).attr('key', 'value');
}
}
Point being when using jQuery what you do is:
$('element').attr('key', 'value');

Unable to add custom elements using the document.execCommand

I am trying to add a custom element into a editable div using document.execCommand detailed at https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand.
But when I try to add a custom polymer element using the execCommand, browser is unable to recognize the custom element even if it was already imported into scope.
var video-id='FnoL3d33U8o'//a youtube video Id
var html = '<p><div><custom-video-element width="454" height="280" video-id="'+videoUrl+'"></custom-video-element></div></p>';
document.execCommand('insertHTML', false, html);
But this doesn't help and the custom-video-element is not recognized by the browser. Please help if there is any alternate ways or if I am running after a mirage!
if you know what element you need to append, then you can use document.createElement.
There are multiple options how to achiev that, but In your case:
var p = document.createElement("p");
var div = document.createElement("div");
var custom = document.createElement("custom-video-element")
custom.setAttribute("video-id", videoUrl);
.. setting another attributes ..
div.appendChild(custom);
p.appendChild(div);
document.appendChild(p);
and that is it. This should work well.
Of course there might be better and easier solutions but in your case this isn't so bad.
if you create bigger html structure inside your JS, you will do something like:
var div = document.createElement("div");
var inner = "<div class="test"><div></div><p class="p"></p></div>;
div.innerHTML = inner;
div.querySelector(".p").appendChild(document.createElement("custom-video-element"));

Is there a way to select an HTML node and copy only the CSS for that node? [duplicate]

I often find nice stylings on the web. To copy the CSS of a DOM element, I inspect that element with Google Chrome Developer Tools, look at the various CSS properties, and copy those manually to my own stylesheets.
Is it possible to easily export all CSS properties of a given DOM element?
Here is the code for an exportStyles() method that should return a CSS string including all inline and external styles for a given element, except default values (which was the main difficulty).
For example: console.log(someElement.exportStyles());
Since you are using Chrome, I did not bother making it compatible with IE.
Actually it just needs that the browsers supports the getComputedStyle(element) method.
Element.prototype.exportStyles = (function () {
// Mapping between tag names and css default values lookup tables. This allows to exclude default values in the result.
var defaultStylesByTagName = {};
// Styles inherited from style sheets will not be rendered for elements with these tag names
var noStyleTags = {"BASE":true,"HEAD":true,"HTML":true,"META":true,"NOFRAME":true,"NOSCRIPT":true,"PARAM":true,"SCRIPT":true,"STYLE":true,"TITLE":true};
// This list determines which css default values lookup tables are precomputed at load time
// Lookup tables for other tag names will be automatically built at runtime if needed
var tagNames = ["A","ABBR","ADDRESS","AREA","ARTICLE","ASIDE","AUDIO","B","BASE","BDI","BDO","BLOCKQUOTE","BODY","BR","BUTTON","CANVAS","CAPTION","CENTER","CITE","CODE","COL","COLGROUP","COMMAND","DATALIST","DD","DEL","DETAILS","DFN","DIV","DL","DT","EM","EMBED","FIELDSET","FIGCAPTION","FIGURE","FONT","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEAD","HEADER","HGROUP","HR","HTML","I","IFRAME","IMG","INPUT","INS","KBD","KEYGEN","LABEL","LEGEND","LI","LINK","MAP","MARK","MATH","MENU","META","METER","NAV","NOBR","NOSCRIPT","OBJECT","OL","OPTION","OPTGROUP","OUTPUT","P","PARAM","PRE","PROGRESS","Q","RP","RT","RUBY","S","SAMP","SCRIPT","SECTION","SELECT","SMALL","SOURCE","SPAN","STRONG","STYLE","SUB","SUMMARY","SUP","SVG","TABLE","TBODY","TD","TEXTAREA","TFOOT","TH","THEAD","TIME","TITLE","TR","TRACK","U","UL","VAR","VIDEO","WBR"];
// Precompute the lookup tables.
for (var i = 0; i < tagNames.length; i++) {
if(!noStyleTags[tagNames[i]]) {
defaultStylesByTagName[tagNames[i]] = computeDefaultStyleByTagName(tagNames[i]);
}
}
function computeDefaultStyleByTagName(tagName) {
var defaultStyle = {};
var element = document.body.appendChild(document.createElement(tagName));
var computedStyle = getComputedStyle(element);
for (var i = 0; i < computedStyle.length; i++) {
defaultStyle[computedStyle[i]] = computedStyle[computedStyle[i]];
}
document.body.removeChild(element);
return defaultStyle;
}
function getDefaultStyleByTagName(tagName) {
tagName = tagName.toUpperCase();
if (!defaultStylesByTagName[tagName]) {
defaultStylesByTagName[tagName] = computeDefaultStyleByTagName(tagName);
}
return defaultStylesByTagName[tagName];
}
return function exportStyles() {
if (this.nodeType !== Node.ELEMENT_NODE) {
throw new TypeError("The exportStyles method only works on elements, not on " + this.nodeType + " nodes.");
}
if (noStyleTags[this.tagName]) {
throw new TypeError("The exportStyles method does not work on " + this.tagName + " elements.");
}
var styles = {};
var computedStyle = getComputedStyle(this);
var defaultStyle = getDefaultStyleByTagName(this.tagName);
for (var i = 0; i < computedStyle.length; i++) {
var cssPropName = computedStyle[i];
if (computedStyle[cssPropName] !== defaultStyle[cssPropName]) {
styles[cssPropName] = computedStyle[cssPropName];
}
}
var a = ["{"];
for(var i in styles) {
a[a.length] = i + ": " + styles[i] + ";";
}
a[a.length] = "}"
return a.join("\r\n");
}
})();
This code is base on my answer for a slightly related question: Extract the current DOM and print it as a string, with styles intact
I'm quoting Doozer Blake's excellent answer, provided above as a comment. If you like this answer, please upvote his original comment above:
Not a direct answer, but with Chrome Developer Tools, you can click inside Styles or Computed Styles, hit Ctrl+A and then Ctrl+C to copy all the styles in those given areas. It's not perfect in the Style tab because it picks up some extra stuff. Better than selecting them one by one I guess. – Doozer Blake 3 hours ago
You can do the same using Firebug for Firefox, by using Firebug's "Computed" side panel.
There are a few ways to almost do this.
Have a look at FireDiff
Also have a look at cssUpdater This is for local CSS only]
And see this Q for more similar tools: Why can't I save CSS changes in Firebug?
Also this paid product claims to be able to do this: http://www.skybound.ca/

Using web audio api live input to control stuff

I would like to use my microphone input to control an image i have. I managed to edit this code by far and get my image affected. There was javascriptNode.onaudioprocess = function() and for some reason it disabled my microphone input checking.
You shouldn't need a Javascript node at all. You should just use a requestAnimationFrame handler to do the section of your code that does:
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var average = getAverageVolume(array);
var array2 = new Uint8Array(analyser2.frequencyBinCount);
analyser2.getByteFrequencyData(array2);
var average2 = getAverageVolume2(array2);
element.style.opacity = average/100;
element2.style.opacity = average2/100;

Use local files with Browser extensions (kango framework)

I'm working on a "browser extension" using "Kango Framework" (http://kangoextensions.com/)
When i want to link a css file i have to use external source (href='http://mysite.com/folder/mysite.css), how should i change the href to make is source from the plugin folder ? (ex: href='mylocalpluginfolder/localfile.css')
i've tried 'localfile.css' and putting the file in the same folder as the JS file.
$("head").append("");
How should i change the json file to make it work ? Should i declare the files as "extended_scripts" or "content_scripts" ?
I've a hard time finding support for this framework, even though the admins are awesome !
Thanks for your help. (please do not suggest to use other solutions, because i won't be able to code plugins for IE and Kango is my only option for this). I didn't find any samples matching my need as the only example available on their site is linking to outside content (christmas tree).
If you want to add CSS in page from content script you should:
Get CSS file contents
Inject CSS code in page
function addStyle(cssCode, id) {
if (id && document.getElementById(id))
return;
var styleElement = document.createElement("style");
styleElement.type = "text/css";
if (id)
styleElement.id = id;
if (styleElement.styleSheet){
styleElement.styleSheet.cssText = cssCode;
}else{
styleElement.appendChild(document.createTextNode(cssCode));
}
var father = null;
var heads = document.getElementsByTagName("head");
if (heads.length>0){
father = heads[0];
}else{
if (typeof document.documentElement!='undefined'){
father = document.documentElement
}else{
var bodies = document.getElementsByTagName("body");
if (bodies.length>0){
father = bodies[0];
}
}
}
if (father!=null)
father.appendChild(styleElement);
}
var details = {
url: 'styles.css',
method: 'GET',
async: true,
contentType: 'text'
};
kango.xhr.send(details, function(data) {
var content = data.response;
kango.console.log(content);
addStyle(content);
});
I do it another way.
I have a JSON containing the styling for specified web sites, when i should change the css.
Using jQuery's CSS gives an advantage on applying CSS, as you may know css() applying in-line css and inline css have a priority over classes and IDs defined in default web pages files and in case of inline CSS it will override them. I find it fine for my needs, you should try.
Using jQuery:
// i keep info in window so making it globally accessible
function SetCSS(){
$.each(window.skinInfo.css, function(tagName, cssProps){
$(tagName).css(cssProps);
});
return;
}
// json format
{
"css":{
"body":{"backgroundColor":"#f0f0f0"},
"#main_feed .post":{"borderBottom":"1px solid #000000"}
}
}
As per kango framework structure, resources must be placed in common/res directory.
Create 'res' folder under src/common folder
Add your css file into it and then access that file using
kango.io.getResourceUrl("res/style.css");
You must add this file into head element of the DOM.
This is done by following way.
// Common function to load local css into head element.
function addToHead (element) {
'use strict';
var head = document.getElementsByTagName('head')[0];
if (head === undefined) {
head = document.createElement('head');
document.getElementsByTagName('html')[0].appendChild(head);
}
head.appendChild(element);
}
// Common function to create css link element dynamically.
function addCss(url) {
var css_tag = document.createElement('link');
css_tag.setAttribute('type', 'text/css');
css_tag.setAttribute('rel', 'stylesheet');
css_tag.setAttribute('href', url);
addToHead(css_tag);
}
And then you can call common function to add your local css file with kango api
// Add css.
addCss(kango.io.getResourceUrl('res/style.css'));