How to inject CSS located on /skin? - firefox

I want to inject a css file located on the skin folder in a browser page.
It is located on chrome://orkutmanager/skin/om.css, accessing manually show the file contents correctly.
I've tried this, but it's not working... What am I missing, or is it impossible?

You can also use the nsIStyleSheetService:
loadCSS: function() {
var sss = Components.classes["#mozilla.org/content/style-sheet-service;1"]
.getService(Components.interfaces.nsIStyleSheetService);
var ios = Components.classes["#mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = ios.newURI("chrome://addon/skin/style.css", null, null);
if(!sss.sheetRegistered(uri, sss.USER_SHEET))
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
}
If you use USER_SHEET, the website's own CSS rules have higher priority than yours. Using AGENT_SHEET, your CSS should have higher priority.
In any way I needed to enforce some rules by using hte !important keyword.

I found this workaround. Read the file then inject it's contents...
function Read(file)
{
var ioService=Components.classes["#mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var scriptableStream=Components
.classes["#mozilla.org/scriptableinputstream;1"]
.getService(Components.interfaces.nsIScriptableInputStream);
var channel=ioService.newChannel(file,null,null);
var input=channel.open();
scriptableStream.init(input);
var str=scriptableStream.read(input.available());
scriptableStream.close();
input.close();
return str;
}
var style = $("<style type='text/css' />");
style.html(Read("chrome://orkutmanager/skin/om.css"));
$("head").append(style);

I found that the link you referred to works if you reference the page document. In my case, using gBrowser.contentDocument worked.
var fileref = gBrowser.contentDocument.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", "resource://extensionid/content/skin/style.css");
gBrowser.contentDocument.getElementsByTagName("head")[0].appendChild(fileref);
Obviously make sure that you can access your css via the resource:// protocol.

Related

Ace modes for XML, JSON work, but not liquid

Setting an ACE editor instance to JSON or XML language mode works great.
But my statement
LiquidMode = ace.require("ace/mode/liquid").Mode,
// fails, ace.require("ace/mode/liquid") returns undefined
Yet the ace/mode/liquid file is defined on the cdn and is returned by it.
Thank you for any ideas or alternatives.
The cdn call and more:
<script src="https://cdn.jsdelivr.net/g/ace#1.2.6(noconflict/ace.js+noconflict/mode-hjson.js+noconflict/mode-liquid.js+noconflict/mode-xml.js+noconflict/theme-chrome.js)">
</script>
// Javascript file
var XMLMode = ace.require("ace/mode/xml").Mode,
JSONMode = ace.require("ace/mode/json").Mode,
LiquidMode = ace.require("ace/mode/liquid").Mode; // fails,
// ace.require("ace/mode/liquid") returns undefined
...
ace_session.setMode(new JSONMode()); // works great
...
ace_session.setMode(new LiquidMode());
When you load ace.js with multiple file syntax, dynamic loading doesn't work, because ace can't determine the url from which it was loaded.
As a workaround you can use
var url = "https://cdn.jsdelivr.net/ace/1.2.6/noconflict/"
ace.config.set("basePath", url)
see https://github.com/ajaxorg/ace/blob/v1.2.6/lib/ace/config.js#L185
Note that you don't need to pass mode object, setMode("ace/mode/liquid") works too.
<script src="https://cdn.jsdelivr.net/g/ace#1.2.6(noconflict/ace.js+noconflict/mode-json.js+noconflict/mode-liquid.js+noconflict/mode-xml.js+noconflict/theme-chrome.js)">
</script>
<script >
// Javascript file
var XMLMode = ace.require("ace/mode/xml").Mode,
JSONMode = ace.require("ace/mode/json").Mode,
LiquidMode = ace.require("ace/mode/liquid").Mode;
debugger
var editor = ace.edit()
var url = "https://cdn.jsdelivr.net/ace/1.2.6/noconflict/";
ace.config.set("basePath", url)
editor.setValue("use core::rand::RngUtil;\n\nfn main() {\n \n}", -1)
editor.setOptions({
autoScrollEditorIntoView: true,
maxLines: 15,
});
document.body.appendChild(editor.container)
editor.session.setMode("ace/mode/rust");
</script>

How to dynamically add view in page or layout

I can't figure out how to programatically add a view into a layout or page.
I need to add views at runtime without using static xml declaration since i need to fetch them from an http requested object... . I didn't find useful informations in the docs.
Anyone knows how to do?
I think you meant to dynamically add some view / controls to the page rather than to navigate into another page.
If so, you just need to add some controls into one of the layouts in your page (only containers [=layouts] can have multiple children.
so, your code (viewmodel/page controller) would look something like:
var layout = page.getViewById("Mycontainer");
// create dynamic content
var label = new Label();
label.text = "dynamic";
// connect to live view
layout.addChild(label)
In addition to having a page included inside your app (normal); you download the xml, css, & js to another directory and then navigate to it by then doing something like page.navigate('downloaded/page-name');
you can also do
var factoryFunc = function () {
var label = new labelModule.Label();
label.text = "Hello, world!";
var page = new pagesModule.Page();
page.content = label;
return page;
};
topmost.navigate(factoryFunc);
https://docs.nativescript.org/navigation#navigate-with-factory-function
You should check out this thread on the {N} forum.
The question is about dynamically loading a page and module from a remote server. The (possible) solution is given in this thread.

Dynamically load jade templates

I'm working on a small documentation website and the content is stored in files. For instance I have two files chapter1.jade and chapter2.jade in a module1/ directory.
I'd like to read the module1/ directory and dynamically include all the chapterX.jade files in it.
I tried to have do directory = fs.readDirSync('module1/') and then in my view:
each item in directory
include item
But jade include doesn't support dynamic values (even `include #{item}) doesn't work. Do you have any idea how I could implement this ?
EDIT: I'd like to generate some code under the each loop (anchor for easy linking) so the solution would preferabily be in the view. I could obviously manually add the anchor in the included files but it is not ideal.
Thanks
Here is the short version of what I've done to make it work. It uses the jade Public API.
var directory = __dirname+'/views/bla/'
, files
, renderedHTML = '';
if( !fs.existsSync(directory) ) {
// directory doesn't exist, in my case I want a 404
return res.status(404).send('404 Not found');
}
// get files in the directory
files = fs.readdirSync(directory);
files.forEach(function(file) {
var template = jade.compile(fs.readFileSync(directory+file, 'utf8'));
// some templating
renderedHTML += '<section><a id="'+file+'" name="'+file+'" class="anchor"> </a>'+template()+'</section>';
});
// render the actual view and pass it the pre rendered views
res.render('view', {
title: 'View',
files: files,
html: renderedHTML
})
And the view just renders the html variable unescaped:
div(class="component-doc-wrap")
!{html}
As #user1737909 say, that's not possible using just jade.
The best way to do this (tho) is building a little Express Dynamic (view) Helpers
DEPECATED IN EXPRESS 3.XX
Check these: Jade - way to add dynamic includes
in addition to kalemas answer you can also write your includes to a file which is included in jade.
in this example I write my includes to include_all.jade. This file is included in a jade file.
If it does not work, check the path ;-)
e.g.
in your app.js
var includes = "path/to/include1\n";
includes += "path/to/include2";
...
incPath = "path/to/include_all.jade";
fs.open(incPath,'w',function(err,fd){
if(err){
throw 'error open file: ' + incPath +" "+ err;
}
var buffer = new Buffer(includes);
fs.write(fd,buffer,0,buffer.length,null,function(err){
if (err)
throw 'error writing file: ' +err;
fs.close(fd,function(){
console.log('file written ' + incPath);
});
});
});
in your jade file
include path/to/include_all.jade

ckeditor how to allow for .insertHtml("<customTag myAttr='value'"></customTag>")

var currentDialog = CKEDITOR.dialog.getCurrent();
currentDialog._.editor.insertHtml("<customTag myAttr='var'></customTag>");
Throws an error, TypeError: Cannot read property 'isBlock' of undefined
If I try .insertHtml("<span>hello</span>") it works just fine.
How can I change ckeditor to allow me to specify my own custom html tags via .insertHtml()? I'd love to just change it to be something like <span class='custom'... or something like that, but I'm having to deal with legacy CMS articles. Using latest ckeditor. Thanks.
You need to modify CKEDITOR.dtd object so editor will know this tag and correctly parse HTML and process DOM:
CKEDITOR.dtd.customtag = { em:1 }; // List of tag names it can contain.
CKEDITOR.dtd.$block.customtag = 1; // Choose $block or $inline.
CKEDITOR.dtd.body.customtag = 1; // Body may contain customtag.
You need to allow for this tag and its styles/attrs/classes in Advanced Content Filter:
editor.filter.allow( 'customtag[myattr]', 'myfeature' );
Unfortunately, due to some caching, in certain situations you cannot modify DTD object after CKEditor is loaded - you need to modify it when it is created. So to do that:
Clone the CKEditor repository or CKEditor presets repository.
Modify core/dtd.js code.
And build your minified package following instructions in README.md - the only requirements are Java (sorry - Google Closure Compiler :P) and Bash.
PS. That error should not be thrown when unknown element is inserted, so I reported http://dev.ckeditor.com/ticket/10339 and to solve this inconvenience http://dev.ckeditor.com/ticket/10340.
I worked around this issue with a combination of createFromHtml() and insertElement()
CKEDITOR.replace('summary', { ... });
var editor = CKEDITOR.instances.summary;
editor.on('key', function(ev) {
if (ev.data.keyCode == 9) { // TAB
var tabHtml = '<span style="white-space:pre"> </span>';
var tabElement = CKEDITOR.dom.element.createFromHtml(tabHtml, editor.document);
editor.insertElement(tabElement);
}
}

Is There an Editable File in Cognos For Importing Stylesheets or Javascript?

I have recently asked where global stylesheets are for editing Cognos 10 styles (Here).
After some discussions with our team we would like to find the CGI or base imported file that Cognos uses to construct it's report viewer pages and dashboard widget holders.
The reason we want to do this is so that we can include all our custom style and javascript in one location. When/If we upgrade Cognos we can be sure of one point of failure with our reports. This would solve our problem of having to re-edit multiple stylesheets (and javascript).
I'm normally familiar with ASP.NET and not CGI-BIN. Is there something akin to a Master page where styles and basic imports are done for a Cognos page? Ideally editing this file would allow us to continue our customizations.
Can this be done? Or are we just insane? We understand the risks concerning upgrades, but are OK with the risks (unless someone can provide a good example of how this technique would not be replicated via version changes).
I think it's fairly common that BI professionals with more traditional web development backgrounds like me and you have no qualms with making changes to the global CSS files and bringing in more JS.
I've explained to you how I run JS in a report - I'd love to add jQuery to our global libraries, but I haven't drummed up enough support for it yet. I can help with the CSS portion though.
In 8.4.1, there's a ton of CSS files referenced by the report viewer. If I were you, I'd render a sample report with the default styling and use Firebug or similar to trace the CSS files being called. You'll find that server/cognos8/schemas/GlobalReportStyles.css is commonly referenced, with some help from server/cognos8/skins/corporate/viewer/QSRVCommon.css - there's also some other files in there that are imported.
I'd imagine you could grep -R '<link rel=\"stylesheet\" type=\"text/css\" href=\"../schemas/GlobalReportStyles.css\"> in the COGNOS directory to see where the file is being called, and either edit that file directly, or create a link to your own JS. Personally, I'd just backup the existing stylesheet and modify the one that is already there.
I'd imagine you could do something similar for the JS - find where it's being called in the template (using grep) and just create a new reference to the file you'd like to create. In my case, I'd do a backflip if I could get jQuery loaded into every report.
Just realized this is a year old. :-( Sorry, first time here. I'll leave it in case anyone is still interested in the topic.
Here is the documentation on customizing Cognos on several levels:
We used an alternative to modifying the system files. We have a shared component "report" containing an HTML object with our particular CSS overrides on it, and/or a link to a custom stylesheet. We then add this on each report with a "Layout Component Reference" from the toolbox. If we want a global change, just change the one item in the component report or custom stylesheet. This works very well for us.
I up-voted both the previous answers to this question. I'll admit I kind of forgot about this question till someone put some activity on it.
We ended up doing a combination of the above techniques. I was able to find the global stylesheets as suggested. What I ended up doing was copying out all the styles that were in that stylesheet and created a new sheet suffixed with *_SystemSytles.css*. I created a second sheet and suffixed it with *_Custom.css*. Then in the original sheet I placed two imports, first importing the system styles and then the custom styles.
For certain reports we have a custom object that is dropped on that brings in its own styles (and JavaScript). This utilizes a similar technique to the second question.
However, what I had to do for import the JavaScript for general use within the entire Cognos site was difficult.
In the core webcontent folder I created a js folder that contained the jQuery and our custom JavaScript files. Then in a series of JavaScript files I included code similar to the following:
/************************
JQUERY UTIL INCLUDE
************************/
function loadjscssfile(filename, filetype, id) {
if (filetype == "js") { //if filename is a external JavaScript file
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
if (id)
fileref.setAttribute("OurCompanyNameAsAnID", id)
}
else if (filetype == "css") { //if filename is an external CSS file
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref != "undefined") {
var headTag = document.head || document.getElementsByTagName('head')[0];
headTag.appendChild(fileref);
}
}
function _PortalLoadJS() {
if (!window._PortalScriptsLoaded) {
var pathParams = [];
var path = location.href;
(function () {
var e,
r = /([^/]+)[/]?/g,
p = path;
while (e = r.exec(p)) {
pathParams.push(e[1]);
}
})();
var baseURL = location.protocol + '//';
for(var i = 1; i < pathParams.length; i++) {
if(pathParams[i] == 'cgi-bin')
break;
baseURL += pathParams[i] + '/';
}
loadjscssfile(baseURL + "js/jquery-1.6.1.min.js", "js");
loadjscssfile(baseURL + "js/Custom.js?pageType=COGNOS_CONNECTION", "js", "SumTotalUtil");
window._PortalScriptsLoaded = true;
}
}
if(!window.$CustomGlobal) {
window.$CustomGlobal= function(func) {
if (!window.$A) {
if (!window.__CustomExecStack) {
window.__CustomExecStack= new Array();
}
window.__CustomExecStack.push(func);
}
else
$A._executeCustomItem(func);
}
}
try {
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if (document.readyState === "complete") {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout(_PortalLoadJS, 10);
}
// Mozilla, Opera and webkit nightlies currently support this event
if (document.addEventListener) {
// Use the handy event callback
document.addEventListener("DOMContentLoaded", function() { _PortalLoadJS(); }, false);
// A fallback to window.onload, that will always work
window.addEventListener("load", _PortalLoadJS, false);
// If IE event model is used
} else if (document.attachEvent) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", function() { _PortalLoadJS(); });
// A fallback to window.onload, that will always work
window.attachEvent("onload", _PortalLoadJS);
}
}
catch (ex) { }
The $A item is an item that I create when the Custom.js file is loaded.
Here are the list of files that I've included this code (at the vary end of the JavaScript):
webcontent\icd\bux\js\bux\bux.core.js
webcontent\ps\portal\js\cc.js
webcontent\rv\CCognosViewer.js
webcontent\rv\GUtil.js
webcontent\rv\viewer.standalone.core.js
These files should cover the Cognos Connection, Report Viewer, and the Dashboards area. If any more are found please let me know and I can update this list.
When linking to the Custom.js file I put a query string on the external resource that the Custom.js file picks up: pageType=COGNOS_CONNECTION. This allows me to do specific load code for the Cognos Connection, Report Viewer, or the Dashboards.
Here is the code in the Custom.js class that inits the $A object:
function _CustomUtilInit() {
try {
if (!window.$j) {
window.setTimeout(_CustomUtilInit, 1);
return;
}
var jScriptTags = $j('SCRIPT[' + Analytics.SCRIPT_ATTR_NAME + '= ' + Analytics.SCRIPT_ATTR_VALUE + ']');
jScriptTags.each( function(i, scriptElem) {
var tag = $j(scriptElem);
if(tag.attr(Analytics.LOADED_SCRIPT_KEY))
return;
var scriptURL = new URI(tag.attr('src'));
var analyticsPageType = scriptURL.getQueryStringValue(Analytics.PAGE_TYPE_QUERY_KEY, Analytics.PageType.REPORT_VIEWER);
if(!window.$A) {
window.$A = new Analytics();
}
window.$A.init(analyticsPageType);
tag.attr(Analytics.LOADED_SCRIPT_KEY, 'true');
});
} catch (e) {
}
}
_CustomUtilInit();
Of course this expects that the jQuery libraries were included before the Custom.js files in each of the previously mentioned JavaScript files.
The URI class is something that I've found on the internet and tweaked for our use. If you have any questions regarding the custom JavaScript loading please leave a comment and I'll do my best to elaborate some more.

Resources