How do I inspect and interact with trails in KRL? - krl

I have a trail that I'm using to track app history in KRL. I'm looking for an easy way to debug the trail, including seeing what is currently on the trail and clearing it.
Is there an easy way to do that in KRL?

The easiest way, for me, to see what is on the trail is to output it's contents to the browser console.
rule inspect_data_on_trail {
select when pageview ".*"
pre {
visitedDomains = ent:visitedDomains;
}
{
emit <|
console.log(visitedDomains);
|>;
}
}
firebug output after running ruleset several times:
To clear entity variables including trails, I usually just write a rule that selects on a domain that isn't part of my app's experience and clear the varaibles when the app is run on that domain.
rule clear_everything {
select when pageview "yahoo\.com"
{
notify("Cleared",":)") with sticky = true;
}
fired {
clear ent:visitedDomains;
}
}
Full example app:
ruleset a60x458 {
meta {
name "trail-debugging"
description <<
trail-debugging
>>
author "Mike Grace"
logging on
}
rule put_data_onto_trail {
select when pageview ".*"
pre {
domain = page:url("domain");
}
{
notify("Thanks for visiting #{domain}","You visit has been recorded") with sticky = true;
}
fired {
mark ent:visitedDomains with domain;
}
}
rule inspect_data_on_trail {
select when pageview ".*"
pre {
visitedDomains = ent:visitedDomains;
}
{
emit <|
console.log(visitedDomains);
|>;
}
}
rule clear_everything {
select when pageview "yahoo\.com"
{
notify("Cleared",":)") with sticky = true;
}
fired {
clear ent:visitedDomains;
}
}
}

Related

How to disable past days in ZK Calendar?

I'm using ZK CE-9.0.0 & zk-calendar-2.1.5 source code.
Currently all the days are enabled in the calendar.
I need to disable the past days (greyed out & no click event), from all the views(Day/Week/Month), but not able to find any such feature directly available.
Can anyone help me with this please?
Thanks,
RAS
I don't think there is such feature.
A workaround would be to disable event click on past days and change the color.
1 . Catch clicks in your controller :
#Wire("#course-calendar")
private Calendars courseCalendar;
#Listen("onEventCreate = #course-calendar")
public void clickCreateEvent(CalendarsEvent event) {
if (event.getBeginDate().before(new Date())) {
// disable click if event is before now
} else {
//do something on event create
}
}
#Listen("onEventEdit = #course-calendar")
public void clickEditEvent(CalendarsEvent event) {
if (event.getBeginDate().before(new Date())) {
// disable click if event is before now
} else {
// do something on event edit
}
}
Grey out events on event creation :
for (MyEvent me : myManager.getEvents()) {
final SimpleCalendarEvent simpleCalendarEvent = new SimpleCalendarEvent();
// set grey color event before now
if (me.startDate < new Date()) {
simpleCalendarEvent.setContentColor("#aaaaaa");
simpleCalendarEvent.setHeaderColor("#aaaaaa");
simpleCalendarEvent.setLocked(true);
} else {
simpleCalendarEvent.setContentColor("#4363d8");
simpleCalendarEvent.setHeaderColor("#4363d8");
simpleCalendarEvent.setLocked(false);
}
simpleCalendarEvent.setContent(me.getContent());
simpleCalendarEvent.setBeginDate(me.startDate);
simpleCalendarEvent.setEndDate(me.endDate);
simpleCalendarEvent.setTitle(me.getTitle());
getSimpleCalendarModel().add(simpleCalendarEvent);
}

Nancy Fx Razor views how to show or hide elements based on user roles

I am playing with Nancy and Forms Authentication. I have a layout view that shows a login or a logout link depending on whether or not the user is authenticated:
#if (#Html.RenderContext.Context.CurrentUser.IsAuthenticated())
{
<p><small><span style="padding-right:15px"><em>#Html.RenderContext.Context.CurrentUser.UserName</em></span>
Logout</small></p>
}
else
{
<p><small>Login</small></p>
}
Throughout my app I will have elements that need to be visible only to those with the correct role.
My question is this. What is the best way to handle this? Should I check for the role in the view and then show/hide the element or in the module show different views depending on the user role?
I ended up using partial views in my layout to provide different navigation sections based on permissions.
#if (#Html.RenderContext.Context.CurrentUser.IsAuthenticated())
{
if (#Html.RenderContext.Context.CurrentUser.Claims.Contains("Admin"))
{
#Html.Partial("Views/Partials/_AdminMenu")
}
else if (#Html.RenderContext.Context.CurrentUser.Claims.Contains("Editor"))
{
#Html.Partial("Views/Partials/_EditorMenu")
}
else if (#Html.RenderContext.Context.CurrentUser.Claims.Contains("Viewer"))
{
#Html.Partial("Views/Partials/_ViewerMenu")
}
else
{
#Html.Partial("Views/Partials/_PublicMenu")
}
}
else
{
#Html.Partial("Views/Partials/_PublicMenu")
}
I will render different views from the module if there are significant differences and send the user to a "permission denied" type view if the get to somewhere they are not supposed to.
I found this to redirect the user to a denied view. Add an after hook to the top of the module.
public class EditUserRoleModule : NancyModule
{
public EditUserRoleModule()
{
// add an after hook to send the user to access denied if they are NOT admin
After += context =>
{
if (context.Response.StatusCode == HttpStatusCode.Forbidden)
context.Response = this.Response.AsRedirect("/denied");
};
this.RequiresAnyClaim(new[] { "admin" });

Open and control new window in KRL/Kynetx

I want to open a new window by clicking on a button (which is injected via Kynetx), but I want this new window to run in the Kynetx sandbox enviornment. This is because the new window will have a button which talks to a REST API, and I want to avoid browser same origin policy. I will also want to modify the DOM of this new window.
//code in Kynetx extension
ruleset a2031x3 {
meta {
name "Open a new window (SO 12030281)"
description << >>
author "Steve Nay"
logging off
}
dispatch {
domain "exampley.com"
}
global { }
rule first_rule {
select when pageview ".*" setting ()
emit <|
// Open a new window and write some content
var newContent = 'some content';
newWin = window.open();
newWin.document.write(newContent);
|>;
}
}
Please help.
You need to wrap that JavaScript code in an emit block, like this:
ruleset a000x0 {
meta {
name "Open a new window (SO 12030281)"
description << >>
author "Steve Nay"
logging off
}
dispatch { }
global { }
rule first_rule {
select when pageview ".*" setting ()
emit <|
// Open a new window and write some content
var newContent = 'some content';
newWin = window.open();
newWin.document.write(newContent);
|>;
}
}
That will open a popup window like you want, and the write() call succeeds:

Make Webview's auto links visible

A Webview will display links in the content HTML as having blue underlines. So if you have something in the HTML like
blah blah
... it is clearly visible as a link.
The Webview also allows you to click on phone numbers and addresses (even if those are just text in the HTML, not links) to launch the Dialer or Maps.
How can one get Webview to display those (Linkify, probably) links with underlines etc? It's easy enough in a TextView since one can get the spans from a TextView and style them, but Webview doesn't expose any way to retrieve that data... at least not that I can see looking through the docs.
Here is some JS code which can be injected to linkify phone numbers, emails and urls:
function linkify() {
linkifyTexts(linkifyPhoneNumbers);
linkifyTexts(linkifyEmails);
linkifyTexts(linkifyWebAddresses1);
linkifyTexts(linkifyWebAddresses2);
}
function linkifyPhoneNumbers(text) {
text = text.replace(/\b\+?[0-9\-]+\*?\b/g, '$&');
return text;
}
function linkifyEmails(text) {
text = text.replace(/(\w+#[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim, '$1');
return text;
}
function linkifyWebAddresses1(text) {
text = text.replace(/(\b(https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/gim, '$1');
return text;
}
function linkifyWebAddresses2(text) {
text = text.replace(/(^|[^\/])(www\.[\S]+(\b|$))/gim, '$1$2');
return text;
}
var linkifyTexts = function(replaceFunc)
{
var tNodes = [];
getTextNodes(document.body,false,tNodes,false);
var l = tNodes.length;
while(l--)
{
wrapNode(tNodes[l], replaceFunc);
}
}
function getTextNodes(node, includeWhitespaceNodes,textNodes,match) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || !/^\s*$/.test(node.nodeValue)) {
if(match){
if(match.test(node.nodeValue))
textNodes.push(node);
}
else {
textNodes.push(node);
}
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
var subnode = node.childNodes[i];
if (subnode.nodeName != "A") {
getTextNodes(subnode,includeWhitespaceNodes,textNodes,match);
}
}
}
}
function wrapNode(n, replaceFunc) {
var temp = document.createElement('div');
if(n.data)
temp.innerHTML = replaceFunc(n.data);
else{
//whatever
}
while (temp.firstChild) {
n.parentNode.insertBefore(temp.firstChild,n);
}
n.parentNode.removeChild(n);
}
Given this:
http://code.google.com/p/android/issues/detail?id=742
it still doesn't seem to be a way to do this from Java directly. One thing that might work is to write some JavaScript code and run it after page is loaded, e.g. as given here:
In Android Webview, am I able to modify a webpage's DOM?
Here's an example of a similar thing:
Disabling links in android WebView
where the idea is to disable links. You may be able to use a similar approach to add some CSS, including underlining. A couple of other SOqs / links that might help:
Android: Injecting Javascript into a Webview outside the onPageFinished Event
Android: Injecting Javascript into a Webview outside the onPageFinished Event
http://iphoneincubator.com/blog/windows-views/how-to-inject-javascript-functions-into-a-uiwebview
Injecting Javascript into a Webview outside the onPageFinished Event (Using DatePicker to set a date on an input of a WebView)
Hope this helps.

How do I make a "notify" box disappear

When I respond to a web event, I would like to make a previously actioned(?) notify box disappear. Is there a KRL way to tell it to go away or does it have to be done through javascript?
If it must be done through javascript, please provide an example
New Shiny Awesomer Answer!
All my previous answers suck! What you really should do is trigger the click event on the close button.
$K(".kGrowl-notification .close").trigger("click");
Just emit that JavaScript when you are responding with a web event.
Better example app:
ruleset a60x469 {
meta {
name "better-close-notify-example"
description <<
better-close-notify-example
>>
author "Mike Grace"
logging on
}
rule put_notify_on_page {
select when pageview ".*"
{
// put notify on page
notify("Hello","I'm on your page") with sticky = true;
// raise web event
emit <|
setTimeout(function() {
app = KOBJ.get_application("a60x469");
app.raise_event("clear_notify");
}, 2000);
|>;
}
}
rule clear_notify {
select when web clear_notify
{
emit <|
$K(".kGrowl-notification .close").trigger("click")
|>;
}
}
}
OLD CRAPPY ANSWER
There are several ways you could accomplish this.
emit JavaScript to hide or replace notification
change style to display:none with set_element_attr
replace_inner action to remove the notification (evil)
Examples:
set_element_attr
set_element_attr(".kGrowl", "style", "display:none");
emit [remove] (evil)
emit <|
$K(".kGrowl").remove();
|>;
emit [hide]
emit <|
$K(".kGrowl").hide();
|>;
replace_html (evil)
replace_html(".kGrowl","");
Full app example:
ruleset a60x468 {
meta {
name "example-clear-notify"
description <<
example-clear-notify
>>
author "Mike Grace"
logging on
}
rule put_notify_on_page {
select when pageview ".*"
pre {
button =<<
<button id="clear-notify">Click me to clear the notify</button>
>>;
}
{
notify("Hello","I'm on your page") with sticky = true;
append("body", button);
emit <|
$K("#clear-notify").click(function() {
app = KOBJ.get_application("a60x468");
app.raise_event("clear_notify");
});
|>;
}
}
rule clear_notify {
select when web clear_notify
{
replace_inner(".kGrowl","");
}
}
}
Example app bookmarklet: => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-clear-notify-dev_bookmarklet.html
Example app run on example.com:
clear button clicked: