I'm trying to pass a callback function as an argument in a previous function that is triggered by a mouseup in a chrome extension. So basically I'm aiming to trigger the quickTranslate function right after the lwsGetText finishes running. But I can't figure out how to do this since the function lwsGetText is triggered by a mouseup. Here's my code:
Content Script (js)
(function () {
// Holds text being selected in browser
var lwsSelectedText = '';
// Adds pop-up to current webpage
function lwsAddContent(callback) {
// Get body tag
var body = document.getElementsByTagName('body');
// add invisible div
document.body.innerHTML += '<div id="myModal" class="modal"><div class="modal-content"><span class="close">×</span><div id="lwsSpanishDiv"><p id="lwsSpanishTitle">Spanish</p><textarea id="lwsSpanishTextArea">Hello</textarea></div><div id="lwsEnglishDiv"><p id="lwsEnglishTitle">English</p><textarea id="lwsEnglishTextArea">Hello 2</textarea></div></div></div>';
callback(lwsSetUpTextGetter);
}
// Make the pop-up visible and set up close button
function lwsActivateContent(callback) {
var modal = document.getElementById('myModal');
// Get the textarea
var txtarea = document.getElementById("myTxtArea");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function () {
modal.style.display = "none";
}
callback(quickTranslate);
}
// Initialize ability to select and grab text from browser
function lwsSetUpTextGetter(callback) {
//Set the onmouseup function to lwsGetText
document.onmouseup = lwsGetText;
//Handling clicking outside webpage?
if (!document.all) document.captureEvents(Event.MOUSEUP);
}
//Gets selected text
function lwsGetText(callback,e) {
// Get access to spanish text area
var spanishText = document.getElementById('lwsSpanishTextArea');
//Get text
lwsSelectedText = (document.all) ? document.selection.createRange().text : document.getSelection();
//if nothing is selected, do nothing
if (lwsSelectedText != '') {
// test: does browser grab text correctly?
alert(lwsSelectedText);
// Set spanish text area content to the selected text from browser
spanishText.value = lwsSelectedText;
// --Error Here--
callback();
}
}
function quickTranslate() {
alert("Quick Translate");
var url = "https://translate.yandex.net/api/v1.5/tr.json/translate",
keyAPI = "trnsl.1.1.20130922T110455Z.4a9208e68c61a760.f819c1db302ba637c2bea1befa4db9f784e9fbb8";
var englishTextArea = document.getElementById('lwsEnglishTextArea');
var spanishTextArea = document.getElementById('lwsSpanishTextArea');
englishTextArea.value = 'Working...';
var xhr = new XMLHttpRequest(),
textAPI = spanishTextArea.value,
langAPI = 'en';
data = "key=" + keyAPI + "&text=" + textAPI + "&lang=" + langAPI;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(data);
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var res = this.responseText;
var json = JSON.parse(res);
if (json.code == 200) {
englishTextArea.value = json.text[0];
}
else {
englishTextArea.value = "Error Code: " + json.code;
}
}
}
}
// When document ready
$(document).ready(function () {
lwsAddContent(lwsActivateContent);
});
})();
If someone could help me figure out how to implement the quickTranslate function as a callback function, that would be awesome! Thanks!
As you know the event handler you're assigning takes one parameter, the event. However you can create a closure around the "callback" variable by doing something like:
function lwsGetText(callback) {
return function (e) {
// Get access to spanish text area
var spanishText = document.getElementById('lwsSpanishTextArea');
//Get text
lwsSelectedText = (document.all) ? document.selection.createRange().text : document.getSelection();
//if nothing is selected, do nothing
if (lwsSelectedText != '') {
// test: does browser grab text correctly?
alert(lwsSelectedText);
// Set spanish text area content to the selected text from browser
spanishText.value = lwsSelectedText;
// --Error Here--
callback();
}
};
}
You would then pass the value quickTranslate as the "callback" parameter when you set the handler, not sure how you're doing that so here is a guess:
myElement.addEventListener("mouseup", lwsGetText(quickTranslate));
Related
Hey guys I need just a little bit of help with this.
So I have modal boxes hiding on my page and when I click on them using the video platform VERSE they work perfectly.
My questions is: How can I call the same modal boxes if I wan to call them from a regular link or button on the page.
Here is the sample:
http://digitalfeast.com/clients/nccv/ncc-verse.html
Here is my Javascript code:
(function() {
(function() {
window.onload = function() {
var frame = document.getElementsByName("verse-iframe")[0].contentWindow;
// Variables below (i.e. "menu-1") reference div id from your markup
function receiveMessage(event) {
var data = (typeof event.data === "String") ? JSON.parse(event.data) : event
var modalWindow1 = document.getElementById("ruben-1");
var modalWindow2 = document.getElementById("ruben-2");
var modalWindow3 = document.getElementById("menu-3");
var modalWindow4 = document.getElementById("menu-4");
// Variables below (i.e. "menu-1") reference the unique callback names entered for your hotspots in the Verse editor
if (data.data["identifier"] === "ruben-1") {
modalWindow1.style.display = "block";
}
if (data.data["identifier"] === "ruben-2") {
modalWindow2.style.display = "block";
}
if (data.data["identifier"] === "menu-3") {
modalWindow3.style.display = "block";
}
if (data.data["identifier"] === "menu-4") {
modalWindow4.style.display = "block";
}
}
var closeBtns = document.getElementsByClassName("modal-close");
for (var i = 0; i < closeBtns.length; i++) {
var btn = closeBtns[i];
btn.onclick = function (event) {
event.target.parentNode.parentNode.style.display = "none";
frame.postMessage({action: "play"}, "*");
};
}
window.addEventListener('message', receiveMessage);
var frame = document.getElementsByName("verse-iframe")[0].contentWindow;
};
}());
}());
Given your code, all you need to do is send the window a message using the Messaging API inside your button click handler.
Your event listener will then execute the receiveMessage function and open your model for ruben-1.
window.onload = () => {
document.querySelector('[data-modal="ruben-1"]').addEventListener("click", (e) => {
let postData = {
identifier: e.target.dataset.modal
};
window.postMessage(postData, "*");
});
window.addEventListener('message', m => {
alert(m.data.identifier);
});
}
<button data-modal="ruben-1">Ruben-1 Video</button>
I need a function, which close the alert box (window) in few seconds automatically:
$("#upload-btn").on('click', function() {
var dt = canvas.toDataURL('image/jpeg');
if (window.Lollipop) {
window.Lollipop.save(dt);
}
$.post('saveImage.php',
{
img : dt
}, function(data) {
if(data){
alert("Image Saved");
}
});
There is no web api function to close the opened alert.
It's NOT possible via standard Web API to close the standard alert box, but you can define your own function or override the alert() function (which is the bad way, better to define own).
const temporaryAlert = function( text, duration ) {
console.assert(typeof text === "string");
console.assert(text.length > 0);
console.assert(typeof duration === "number");
const item = document.createElement("div");
item.innerText = text;
// item.style - add some CSS-stuff to customize the box style
window.setTimeout(() => item.parentNode.removeChild(item), duration);
return document.body.appendChild(item);
};
I have developed chrome extension , I have added ,
chrome.browserAction.onClicked.addListener
which will start the script once clicked on , the script in turn will add a div at the bottom of the web page on the tab the browser action is clicked ,
All I have to do is , I need to add a close link which will stop the content script and close the div at the bottom ,
I have tried windows.close() , self.close() but nothing seems to work ,I would atleast want it to work in a way that 2nd time some one clicks on browser action, the script should stop.
Here is my code,
background.js
chrome.browserAction.onClicked.addListener( function() {
chrome.tabs.executeScript( { file: 'myscript.js' } );
});
myscript.js
document.body.appendChild(div);
document.addEventListener("click",
function (e) {
e.preventDefault();
var check = e.target.getAttribute("id");
var check_class = e.target.getAttribute("class");
if(check=="ospy_" || check=="ospy_id" || check=="ospy_text" || check=="ospy_el" || check=="ospy_class" || check=="ospy_name" || check=="ospy_href" || check=="ospy_src"|| check=="ospy_wrapper"|| check=="ospy_style"|| check=="ospy_rx"|| check=="ospy_con"|| check_class=="ospy_td"|| check=="ospy_main_tab"|| check_class=="ospy_tab" || check_class=="ospy_ip"|| check_class=="ospy_lab")
{
}
else{
document.getElementById('ospy_id').value = "";
document.getElementById('ospy_class').value = "";
document.getElementById('ospy_el').value = "";
document.getElementById('ospy_name').value = "";
document.getElementById('ospy_style').value = "";
document.getElementById('ospy_href').value = "";
document.getElementById('ospy_text').value = "";
document.getElementById('ospy_src').value = "";
document.getElementById('ospy_con').value = "";
document.getElementById('ospy_').value = "";
document.getElementById('ospy_rx').value = "";
var dom_id=e.target.getAttribute("id");
// var dom_id = e.target.id.toString();
var dom_name = e.target.name.toString();
var dom_class = e.target.className.toString();
// var dom_class = this.class;
var dom_html = e.target.innerHTML;
var dom_href = e.target.getAttribute("href");
var dom_text = e.target.text;
var dom_el= e.target.tagName;
var dom_src= e.target.src;
//var XPATH = e.target.innerHTML;
var rel_xpath = "";
var field ="";
var field_value = "";
field="id";
field_value = dom_id;
rel_xpath = dom_el+"[#"+field+"='"+field_value+"']";
if(dom_id == null){
field="href";
field_value= dom_href;
//var rel_xpath = dom_el+"[contains(text(), '"+dom_text+"')]";
rel_xpath = dom_el+"[#"+field+"='"+field_value+"']";
if(dom_href==null || dom_href=="#")
{
field="src";
field_value= dom_src;
rel_xpath = dom_el+"[#"+field+"='"+field_value+"']";
//rel_xpath = "nope nothing";
if(dom_src==null)
{
var rel_xpath = dom_el+"[contains(text(), '"+dom_text+"')]";
if(dom_text=="")
{
field="class";
field_value= dom_class;
rel_xpath = dom_el+"[#"+field+"='"+field_value+"']";
}
}
}
}
var con_xpath = "";
var con_xpath = dom_el+"[contains(text(), '"+dom_text+"')]";
if(dom_text==null)
{
con_xpath = "NA";
}
var css ="color: ";
css += getComputedStyle(e.target).color;
css +="\nWidth: ";
css += getComputedStyle(e.target).width;
css +="\nHeight: ";
css += getComputedStyle(e.target).height;
css +="\nbg: ";
css += getComputedStyle(e.target).background;
css +="\nfont: ";
css += getComputedStyle(e.target).font;
css +="\nvertical-align: ";
css += getComputedStyle(e.target).verticalalign;
css +="\nmargin: ";
css += getComputedStyle(e.target).margin;
var node = getXPath(e.target.parentNode);
document.getElementById('ospy_id').value = dom_id;
document.getElementById('ospy_class').value = dom_class;
document.getElementById('ospy_el').value = dom_el;
document.getElementById('ospy_name').value = dom_name;
document.getElementById('ospy_style').value = css;
document.getElementById('ospy_href').value = dom_href;
document.getElementById('ospy_text').value = dom_text;
document.getElementById('ospy_src').value = dom_src;
document.getElementById('ospy_').value = node;
document.getElementById('ospy_rx').value =rel_xpath;
document.getElementById('ospy_con').value =con_xpath;
}},
false);
window.close() is for closing a window, so no wonder it does not work.
"Unloading" a content-script is not possible, but if you want to remove an element (e.g. your div) from the DOM, just do:
elem.parentNode.removeChild(elem);
(Whether you bind this behaviour to a link/button in your <div> or have the browser-action, trigger an event in the background-page that sends a message to the corresponding content-script which in turn removes the element is up to you. (But clearly the former is much more straight-forward and efficient.)
If you, also, want your script to stop performing some other operation (e.g. handling click events) you could (among other things) set a flag variable to false (when removing the <div>) and then check that flag before proceeding with the operation (e.g. handling the event):
var enabled = true;
document.addEventListener('click', function (evt) {
if (!enabled) {
/* Do nothing */
return;
}
/* I am 'enabled' - I'll handle this one */
evt.preventDefault();
...
/* In order to "disable" the content-script: */
div.parentNode.removeChild(div);
enabled = false;
Notes:
If you plan on re-enabling the content-script upon browser-action button click, it is advisable to implement a little mechanism, where the background-page sends a message to the content-script asking it to re-enable itself. If the content-script is indeed injected but disabled, it should respond back (to confirm it got the message) and re-enable itself. If there is no response (meaning this is the first time the user clicks the button on this page, the background-page injects the content script.
If it is likely for the content script to be enabled-disabled multiple times in a web-pages life-cycle, it would be more efficient to "hide" the <div> instead of removing it (e.g.: div.style.display = 'none';).
If you only need to disable event handler, instead of using the enabled flag, it is probably more efficient to keep a reference to the listener you want to disable and call removeEventListener().
E.g.:
function clickListener(evt) {
evt.preventDefault();
...
}
document.addEventListener('click', clickListener);
/* In order to "disable" the content-script: */
div.parentNode.removeChild(div);
document.removeEventListener('click', clickListener);
I am trying to extract the textbox value and send it to server but when I paste something in the var sd=$('#TextBoxUrl').val(); does not get the data on first paste event when I paste again then it gets the date from the textbox. What can be the problem?
$('.urldetailstextbox').bind('paste', function () {
$("#DivUrlDetails").data('ready', false);
divprogress.style.display = "block";
DivUrlDetails.style.display = "none";
$('#spandetail').append();
$('#spanurl').append();
$('#spantitle').append();
var sd = $('#TextBoxUrl').val();
$("#divlinksave").data('requesting', true);
console.log(sd);
}
You have to catch the paste event and wait a slight time to let the val be populated.
https://stackoverflow.com/a/1503425/336542
$('input').bind('paste', function () {
var element = this;
setTimeout(function () {
var text = $(element).val();
// do something with text
}, 100);
});
I'm using the following placeholder plugin
(function($){
var ph = "PLACEHOLDER-INPUT";
var phl = "PLACEHOLDER-LABEL";
var boundEvents = false;
var default_options = {
labelClass: 'placeholder'
};
//check for native support for placeholder attribute, if so stub methods and return
var input = document.createElement("input");
if ('placeholder' in input) {
$.fn.placeholder = $.fn.unplaceholder = function(){}; //empty function
delete input; //cleanup IE memory
return;
};
delete input;
//bind to resize to fix placeholders when the page resizes (fields are hidden/displayed, which can change positioning).
$(window).resize(checkResize);
$.fn.placeholder = function(options) {
bindEvents();
var opts = $.extend(default_options, options)
this.each(function(){
var rnd=Math.random().toString(32).replace(/\./,'')
,input=$(this)
,label=$('<label style="position:absolute;display:none;top:0;left:0;"></label>');
if (!input.attr('placeholder') || input.data(ph) === ph) return; //already watermarked
//make sure the input tag has an ID assigned, if not, assign one.
if (!input.attr('id')) input.attr('id', 'input_' + rnd);
label .attr('id',input.attr('id') + "_placeholder")
.data(ph, '#' + input.attr('id')) //reference to the input tag
.attr('for',input.attr('id'))
.addClass(opts.labelClass)
.addClass(opts.labelClass + '-for-' + this.tagName.toLowerCase()) //ex: watermark-for-textarea
.addClass(phl)
.text(input.attr('placeholder'));
input
.data(phl, '#' + label.attr('id')) //set a reference to the label
.data(ph,ph) //set that the field is watermarked
.addClass(ph) //add the watermark class
.after(label) //add the label field to the page
//setup overlay
itemFocus.call(this);
itemBlur.call(this);
});
};
$.fn.unplaceholder = function(){
this.each(function(){
var input=$(this),
label=$(input.data(phl));
if (input.data(ph) !== ph) return;
label.remove();
input.removeData(ph).removeData(phl).removeClass(ph).unbind('change',itemChange);
});
};
function bindEvents() {
if (boundEvents) return;
//prepare live bindings if not already done.
$("form").live('reset', function(){
$(this).find('.' + ph).each(itemBlur);
});
$('.' + ph)
.live('keydown',itemFocus)
.live('mousedown',itemFocus)
.live('mouseup',itemFocus)
.live('mouseclick',itemFocus)
.live('focus',itemFocus)
.live('focusin',itemFocus)
.live('blur',itemBlur)
.live('focusout',itemBlur)
.live('change',itemChange);
;
$('.' + phl)
.live('click', function() { $($(this).data(ph)).focus(); })
.live('mouseup', function() { $($(this).data(ph)).focus(); });
bound = true;
boundEvents = true;
};
function itemChange() {
var input = $(this);
if (!!input.val()) {
$(input.data(phl)).hide();
return;
}
if (input.data(ph+'FOCUSED') != 1) {
showPHL(input);
}
}
function itemFocus() {
$($(this).data(ph+'FOCUSED',1).data(phl)).hide();
};
function itemBlur() {
var that = this;
showPHL($(this).removeData(ph+'FOCUSED'));
//use timeout to let other validators/formatters directly bound to blur/focusout work
setTimeout(function(){
var input = $(that);
//if the item wasn't refocused, test the item
if (input.data(ph+'FOCUSED') != 1) {
showPHL(input);
}
}, 200);
};
function showPHL(input, forced) {
var label = $(input.data(phl));
//if not already shown, and needs to be, show it.
if ((forced || label.css('display') == 'none') && !input.val())
label
.text(input.attr('placeholder'))
.css('top', input.position().top + 'px')
.css('left', input.position().left + 'px')
.css('display', 'block');
//console.dir({ 'input': { 'id':input.attr('id'), 'pos': input.position() }});
}
var cr;
function checkResize() {
if (cr) window.clearTimeout(cr);
cr = window.setTimeout(checkResize2, 50);
}
function checkResize2() {
$('.' + ph).each(function(){
var input = $(this);
var focused = $(this).data(ph+'FOCUSED');
if (!focused) showPHL(input, true);
});
}
}(jQuery));
It applies the placeholder attribute to form fields in browsers that do not natively support the placeholder attribute (ex. IE9). It works for statically loaded text fields, however for text fields that are loaded via ajax, the placeholder does not appear.
Is it possible to achieve this 'watermark' effect on text fields that are loaded via ajax?
What happens if you trigger the window resize function after adding in new inputs?
$(window).trigger('resize')
You could apply the plugin to newly created controls after the AJAX call completes. Forgive the pseudo-code as I'm not really sure about how your AJAX calls are working:
$.ajax({
url: "test.html",
cache: false
}).done(function( result ) {
field = $('<input>').html(result);
$("#results").append(field);
field.placeholder();
});
Another option is that you could use jQuery's .on() method to bind dynamically created controls to the function--but it wants an event (like click). I'm not sure how you would do that. Maybe something like this:
$( 'body' ).on('click','input.addField', function(e){
$(this).placeholder();
});
I know this won't work, but maybe it helps get you brainstorm solutions.