Button handling and layer visibility in Greasemonkey - javascript

I have a Greasemonkey script that I've been building for a game. The idea is to have info about the game in a div that will pop up when a button (which is added by my script) on the page is clicked.
I'm using z-index because when I just display the div over the top of the game screen, some of the images show through. So, basically what I need to do is change the z-index of my div based on the value of a variable and/or button click. However, I cannot get my div to come to the front when I click my button.
Here's what I have so far:
// ==UserScript==
// #name Test Script
// #namespace http://therealmsbeyond.com/
// #description Test
// #include an_include.js
// #include another_include.js
// #require json.js
// ==/UserScript==
var VERSION = 1;
var WEBSITEURL = 'http://therealmsbeyond.com/';
var SCRIPTNAME = 'Test';
var SENDINFODELAY = 600000;
var UPDATEDELAY = 604800000;
var ZINDEX_UNDER = -100;
var ZINDEX_OVER = 111111;
var Options = {
'mapVisible' : false,
'showHostile' : false,
'showAlliance' : false,
'showBookmarks' : false
}
function custom_setValue(k,v){
GM_setValue(k,v);
}
function custom_getValue(k,dv){
return(GM_getValue(k,dv));
}
function custom_deleteValue(k){
GM_deleteValue(k);
}
function getSavedInfo(){
return(custom_getValue('ajaxparams',null));
}
function getSavedServerId(){
return(custom_getValue('sid'));
}
var e = document.createElement('div');
var idAttr = document.createAttribute('id');
var styleAttr = document.createAttribute('style');
idAttr.nodeValue = 'shadow_map_container';
styleAttr.nodeValue = 'background-color:white;top:150px;left:75px;position:absolute;height:600px;width:600px;';
e.setAttributeNode(idAttr);
e.setAttributeNode(styleAttr);
var c = '<strong>This is the map window.</strong>';
e.innerHTML = c;
document.body.appendChild(e);
if(Options.mapVisible == true)
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_OVER;
}
else
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_UNDER;
}
function showHide()
{
if(Options.mapVisible == true)
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_UNDER;
Options.mapVisible = false;
}
else
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_OVER;
Options.mapVisible = true;
}
}
var btnStr = '<a class="navTab" target="_top" onclick="showHide();return false;" href="javascript:void(0)"><span>Shadow Mapper</span></a>';
var myNavContainer = document.getElementById('main_engagement_tabs');
var inner = myNavContainer.innerHTML;
var newStr = btnStr + inner;
myNavContainer.innerHTML = newStr;

This is not a z-index problem, it's a coding style and event-listener problem.
You cannot activate a button that way in a Greasemonkey script. showHide() resides in the GM sandbox, the page's JS cannot reach it from an onclick.
(One more, of many, reasons why inline JS should be avoided.)
In this example, you would activate the link like so:
function showHide()
{
if(Options.mapVisible == true)
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_UNDER;
Options.mapVisible = false;
}
else
{
document.getElementById('shadow_map_container').style.zIndex = ZINDEX_OVER;
Options.mapVisible = true;
}
return false;
}
var btnStr = '<a class="navTab" target="_top"><span>Shadow Mapper</span></a>';
var myNavContainer = document.getElementById('main_engagement_tabs');
var inner = myNavContainer.innerHTML;
var newStr = btnStr + inner;
myNavContainer.innerHTML = newStr;
var btn = document.querySelector (".main_engagement_tabs > a.navTab");
btn.addEventListener ("click", showHide, true);

Related

how can I manipulate ScriptUI state in Illustrator based on document state instead of button click?

Trying to hide a button depending on current document name. If the document is open then the button is hidden else display button.
The current code is not displaying the button at all.
if(!app.documents.length){
add_group_Ai();
}
else{
var currentDocument = app.activeDocument.name;
var str = aiProjectFile.fullName;
var fileName = str.substr(str.lastIndexOf("/")+1,str.length);
if(fileName == currentDocument){
alert('document already open');
remove_group_Ai();
}
}
function remove_group_Ai(){
group_Ai.remove(this.parent);
dialog.layout.layout(true);
}
function add_group_Ai(){
// GROUP_AI
// ========
var group_Ai = panel_namePlate.add("group", undefined, {name: "group_Ai"});
group_Ai.orientation = "column";
group_Ai.alignChildren = ["fill","top"];
group_Ai.spacing = 10;
group_Ai.margins = 5;
group_Ai.alignment = ["center","top"];
var btn_AiProj = group_Ai.add("button", undefined, undefined, {name: "btn_AiProj"});
btn_AiProj.text = "Open Illustrator Project";
btn_AiProj.alignment = ["center","top"];
btn_AiProj.onClick = function(){
aiProjectFile = File.openDialog();
if (aiProjectFile) {
var str = aiProjectFile.fullName;
var fileName = str.substr(str.lastIndexOf("/")+1,str.length);
projPathText.text = fileName;
app.open(aiProjectFile);
}
};

javascript webservice call and settimeout

i'm currently developing an application that relies on webservice calls in order to create a tree-like "menu", everything works as intended but i realized not all the target audience has a fast internet connection like i have right now on the development environment. my goal is to show a loading "screen" while the javascript function creates and then adds the elements to the DOM, the flowchart is as follows:
user click on the "expand" image of a node
user sees a div loading gif
user is presented with the childnodes
i'm not sure where i should put the timeout
my code:
...
elemento_tema_imagem_esconde_mostra.addEventListener("click", Get_Feat);
...
function Get_Feat(event) {
Tema_Expandido = event.target.parentNode;
if (typeof (Tema_Expandido.getElementsByTagName("ul")[0]) === "undefined") {
sMNID = event.target.parentNode.getElementsByTagName("a")[0].getAttribute("mnid");
var service = new WebJSON;
service.GetFeat(sMNID, SuccessCallback_Get_Feat, OnfailureCallback_Get_Feat);
} else {
//debugger;
var elemento = Tema_Expandido.getElementsByTagName("ul")[0];
var imagem_esconder_mostar = elemento.parentNode.childNodes[0];
var style = window.getComputedStyle(elemento, null);
if (style.display == "block") {
elemento.style.display = "none";
imagem_esconder_mostar.src = "Content/Images/img_abrir_22_22.png";
} else if (style.display == "none") {
elemento.style.display = "block";
imagem_esconder_mostar.src = "Content/Images/img_fechar_22_22.png";
}
}
};
function SuccessCallback_Get_Feat(Resultado_Get_Feat) {
var colleccao_Feat = JSON.parse(Resultado_Get_Feat);
var lista_feat = document.createElement("ul");
lista_feat.setAttribute("class", "lista-sem-bullets");
for (var i = 0; i < colleccao_Feat.length; i++) {
var elemento_feat = document.createElement("li");
var elemento_feat_imagem_esconde_mostra = document.createElement("img");
var elemento_feat_imagem_no = document.createElement("img");
var elemento_feat_link = document.createElement("a");
if (colleccao_Feat[i].FILHOS > 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/img_abrir_22_22.png";
elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Compo);
} else if (colleccao_Feat[i].FILHOS = 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/seta_dir_26_20.png";
}
//elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Feat);
//elemento_feat_imagem_no.src = "Content/Images/feat.png"
elemento_feat_link.setAttribute("FNID", colleccao_Feat[i].FNID);
elemento_feat_link.innerText = colleccao_Feat[i].NAMEDESC;
elemento_feat.appendChild(elemento_feat_imagem_esconde_mostra);
elemento_feat.appendChild(elemento_feat_imagem_no);
elemento_feat.appendChild(elemento_feat_link);
lista_feat.appendChild(elemento_feat);
};
document.getElementById("myModal_Loading").style.display = "none";
Tema_Expandido.appendChild(lista_feat);
Tema_Expandido.childNodes[0].src = "Content/Images/img_fechar_22_22.png";
};
function OnfailureCallback_Get_Feat(error) {
//displaying error on alert box
alert(error);
};
any help will be much appreciated

(Javascript) SlideShow Not Working

Hello fellow stackoverflow members,
I've been trying to make a Slideshow. I've referenced from many other sites including this one but the pictures aren't showing up in the container element nor are the "prev" and "next" buttons functioning properly. I'd appreciate it if I got help! :)
my code:
var photos = newArray ();
photos[0] = "img/image(2).jpg";
photos[1] = "img/image(4).jpg";
photos[2] = "img/image(6).jpg";
photos[3] = "img/image(8).jpg";
photos[4] = "img/image(10).jpg";
photos[5] = "img/image(12).jpg";
photos[6] = "img/image(14).jpg";
photos[7] = "img/image(16).jpg";
photos[8] = "img/image(18).jpg";
photos[9] = "img/image(20).jpg";
photos[10] = "img/image(22).jpg";
photos[11] = "img/image(24).jpg"
//END OF PHOTOS ARRAY//
var i = 0;
var k = photos.length-1;
function next.onclick() {
var img= document.getElementById("image-container");
img.src = photos[i];
if (i < k ) {
i++;
}else {
i = 0; }
}
function prev.onclick() {
var img= document.getElementById("image-container");
img.src=photos[i];
if)i > 0) {i--;}
else {i = k; }
}
getImageArray = function(containerId) {
var containerElement = document.getElementById(container);
if (containerElement) {
var imageArray = containerElement.getElementById("container");
return photos[i];
} else {
return null;
}
}
this is what my slideshow looks like (it's broken)
http://prntscr.com/5dcfzq
The share button isn't important, I can make that work at least.
The main problem is that the pictures aren't showing and the back and foward buttons are messed up :'(
p.s ( I'm not sure if part of the reason is how I'm linking to the "next" or "back" functions with the div tag, because i'm this is how i'm doing it :
<div id = "back" onclick = "prev()"></div>
OK ... to summarize ...
1. var photos = newArray ();
There needs to be a space between new and Array, so ...
var photos = new Array();
2. function prev.onclick() { needs to be just function prev() {
3. Same with next.onclick() based on usage in HTML.
4. In prev() ... if)i > 0) {i--;} should be ...
if (i > 0) { i--; }
5. WRONG: Also in prev()' ... else should bei = k-1;`
6. DO NOT NEED Not sure why you have the getImageArray function at all.
7. This assumes there is an '' tag in the HTML.
UPDATE:
Here's the code that works ... this all goes in the body:
These are my assumptions in the body ...
<img id="image-container" />
<div id="back" onclick="prev()">Previous</div>
<div id="next" onclick="mext()">Next</div>
The script code MUST be at the end of the body ...
<script>
var photos = new Array ();
photos[0] = "img/image(2).jpg";
photos[1] = "img/image(4).jpg";
photos[2] = "img/image(6).jpg";
photos[3] = "img/image(8).jpg";
photos[4] = "img/image(10).jpg";
photos[5] = "img/image(12).jpg";
photos[6] = "img/image(14).jpg";
photos[7] = "img/image(16).jpg";
photos[8] = "img/image(18).jpg";
photos[9] = "img/image(20).jpg";
photos[10] = "img/image(22).jpg";
photos[11] = "img/image(24).jpg"
//END OF PHOTOS ARRAY//
// Here, I set the img variable so that it can be re-used.
// I also loaded the first image ...
var i = 0;
var k = photos.length-1;
var img = document.getElementById("image-container");
img.src = photos[i];
function next() {
img.src = photos[i];
if (i<k) {
i++;
} else {
i = 0;
}
}
function prev() {
img.src=photos[i];
if (i>0) {
i--;
} else {
i = k;
}
}
</script>

How to create dynamic instances of JQueryTE text editor

I am attempting to create a small program that incorporates dynamically created instances of this editor.
I have it working except for the ability to create a button that opens/closes the editor.
jsFiddle of what I've got so far.
"use strict";
$(document).ready(function() {
var createPad = $("#createPad").click(function () {
var body = document.getElementById("body");
var editorNumberCounter = 1;
var toggleOnOffCounter= 1;
var editorName = '.'+ (editorNumberCounter++);
var status = document.createElement('div');
status.className = "status";
status.id = "status";
var editorName= document.createElement('span');
editorName.className = "status";
editorName.id = "status";
$(body.appendChild(status));
$(body.appendChild(editorName));
var toggle = status.id + toggleOnOffCounter++;
$(editorName).jqte();
// settings of status
var jqteStatus = true;
$(toggle).click(function()
{
jqteStatus = jqteStatus ? false : true;
$(editorName).jqte({toggle : jqteStatus})
});
});
});
I made up some changes to your code an now seems to work.
I try to explain them point by point:
variabiles editorNumberCounter and toggleOnOffCounter must be globally scoped or you lose the incremented value
ID of elements (dynamically created or not) MUST be unique, so I create the div and span element considering the counter
for dynamically created elements you must use the bind method or the event will not be bind
the toggle property not exist! You must use the status property
the element onto JQTE is binded is get as next element after the clicked element
Code:
var editorNumberCounter = 0;
var toggleOnOffCounter = 0;
$(document).ready(function () {
var createPad = $("#createPad").click(function () {
var body = document.getElementById("body");
var editorName = '.' + editorNumberCounter++;
toggleOnOffCounter++;
var status = document.createElement('div');
status.className = "status";
status.id = "div_status" + editorNumberCounter;
var editorName = document.createElement('span');
editorName.className = "status";
editorName.id = "span_status" + editorNumberCounter;
$(body.appendChild(status));
$(body.appendChild(editorName));
$(editorName).jqte();
// settings of status
var jqteStatus = true;
$("#div_status" + editorNumberCounter).bind("click",function () {
jqteStatus = jqteStatus ? false : true;
$(this).next().jqte({
status: jqteStatus
})
});
});
});
Here is a working fiddle: http://jsfiddle.net/IrvinDominin/UfhNQ/14/

Javascript dialog script feedback needed

I am writing a Javascript dialog script which is seen in a lot of typical Role Playing Games.alt text http://www.dailynintendo.com/wp-content/uploads/2008/12/luminous-arc-2-dialogue.jpg
At the moment I got an array with text strings which you can skip trough. I got at the point where you can make a decision and based on the input a different string will show.
However I don't think this is the right way to do it. These are the requirements for the script:
Support for multiple dialog scripts
multiple characters
user decision input ("Do you like me?" -yes -no)
This is my code at the moment:
// Intro script
var script_intro = [];
script_intro[0] = 'Hello how are you?';
script_intro[1] = 'So I heard..';
script_intro[2] = 'This is a cool game!';
script_intro[3] = [];
script_intro[3][0] = 'Do you like me?';
script_intro[3][1] = [];
script_intro[3][1][0] = 'Jah';
script_intro[3][1][1] = 4;
script_intro[3][2] = [];
script_intro[3][2][0] = 'Nah';
script_intro[3][2][1] = 5;
// Intro script: variation I
var script_intro_1 = [];
script_intro_1[0] = 'I love you too!';
// Intro script: variation II
var script_intro_2 = [];
script_intro_2[0] = 'Damn you...';
function initDialog()
{
// This is where the text will be shown
var dialog = document.getElementById('dialog');
var content = document.getElementById('content');
var nextButton = document.getElementById('nextButton');
var optionButton_1 = document.getElementById('optionButton_1');
var optionButton_2 = document.getElementById('optionButton_2');
// How fast the characters will appear after each other (milliseconds)
var scrollSpeed = 50;
}
// Scroll text per line, character
function scrollText(script, line)
{
var char = 0;
// If this line contains a question that requires user input
if(typeof(script[line]) == 'object')
{
var textScroller = setInterval(
function()
{
// Add the string char for char
content.innerHTML += script[line][0][char];
char ++;
if(char >= script[line][0].length)
{
clearInterval(textScroller);
// Show options
options(script, line);
}
}, scrollSpeed);
}
else
{
var textScroller = setInterval(
function()
{
content.innerHTML += script[line][char];
char++;
if(char >= script[line].length)
{
clearInterval(textScroller);
// Show next line
next(script, line);
};
}, scrollSpeed);
}
}
function next(script, line)
{
line = line + 1;
// Last line has been shown
if(script[line] == undefined)
{
//alert('End of dialog');
}
else
{
nextButton.style.visibility = 'visible';
nextButton.onclick = function()
{
nextButton.style.visibility = 'hidden';
content.innerHTML = '';
scrollText(script, line);
}
}
}
function options(script, line)
{
optionButton_1.innerHTML = script[line][1][0];
optionButton_2.innerHTML = script[line][2][0];
optionButton_1.style.visibility = 'visible';
optionButton_2.style.visibility = 'visible';
optionButton_1.onclick = function()
{
optionButton_1.style.visibility = 'hidden';
optionButton_2.style.visibility = 'hidden';
content.innerHTML = '';
scrollText('script_intro_1', 0);
}
optionButton_2.onclick = function()
{
optionButton_1.style.visibility = 'hidden';
optionButton_2.style.visibility = 'hidden';
content.innerHTML = '';
scrollText('script_intro_2', 0);
}
}
html
<body onload="scrollText(script_intro, 0)">
<h1>rpg</h1>
<a id="reset" href="#">Reset</a>
<div id="device">
<div id="dialog">
<strong>NPC:</strong>
<div id="content"></div>
<a id="nextButton" href="#">Next</a>
<a id="optionButton_1" href="#"></a>
<a id="optionButton_2" href="#"></a>
</div>
</div>
</body>
I could really use some feedback. What is the best way to write such script with the requirements above? Is using JSON or XML a better option than an Array for the dialog scripts?
I especially need some hints on how to implement multiple choices in the script.
Thank you!
If this is a script that has a scripted flow to it, I would use the state machine pattern.
http://www.eventhelix.com/RealtimeMantra/HierarchicalStateMachine.htm
There are tons of links, I just grabbed the first I searched from google. What I would do is have a state for each situation the user will presented with options. Each option would be a transition to another state. So for instance
function State(questionText){
this.transitionsOut = [];
this.questionText = questionText;
}
State.prototype = {
transitionsOut:null,
questionText:null,
}
function Transition(startState, endState, optionText){
startState.transitionsOut[startState.transitionsOut.length] = this;
this.start = startState;
this.end = endState;
}
Transition.prototype = {
start:null,
end:null,
optionText:null
}
Then what you can do, is make your state machine, and then for the current state, print out your State Message, then underneath list each option for that state.
var startState = new State('Where do you want to go');
var north = new State('North');
var south = new State('South');
var transition1 = new Transition(startState,north,'Lets go north');
var transition2 = new Transition(startState,south,'Lets go south');
The code to then display what is in the current state, and the options is trivial, as is the transition from one state to another based on what the user picks.

Categories

Resources