I don't want to duplicate my components or use templating application.
Then, how can I do that?
you could do something like the chrome.i18n api for chrome apps and extensions. https://developer.chrome.com/extensions/i18n the general idea is each language has a json file with all the text. sub foldered by language.
_locals
\- en
| \- messages.json
- es
\- messages.json
content of the json file just needs to be valid json. nothing exciting just key value pairs
messages.json
{
elementName: 'my-element',
elementVersion: '0.1'
}
the user of the element could set the language with a attribute
<my-element language="en"></my-element>
then in your element you would make a XMLHttpRequest to get the text.
getLanguageText: function() {
var xhr = new XMLHttpRequest();
var url = '/my-element/_locals/' + this.language + '/messages.json';
xhr.open("GET", url, true);
xhr.responseType = 'json';
xhr.send();
xhr.onload = function (e) {
this.text = e.target.response;
}.bind(this);
xhr.onerror = function (e) {
console.error('Error Loading Language Text', e);
};
};
the real issue i guess with this approach is it being dependent on path of the json file staying static. not a real big deal if everyone is going to get the element from say bower where it will always be in the bower_components/my-element/_locals/en/messages.json location.
then you could use the values in your html just like any other polymer value.
{{text.elementName}}
maybe this will help. /shrug
edit: i didn't see this # time of post but you might need to bind this to the onload callback. in the original answer this would be the xhr object. by using .bind(this) the callback would correctly target the custom element. ill edit answer.
Related
I am kind of new to javascript and building websites, I program c# most of the times.
I am trying to build something and I need to use google translate api, the problem that is cost money so I prefer use Free API so I found this.
https://ctrlq.org/code/19909-google-translate-api
so I changed it a bit and tried alone, because I wasn't sure what e type ment.
so this is my code:
function doGet(text) {
var sourceText = text;
var translatedText = LanguageApp.translate('en', 'iw', sourceText);
var urllog = "https://translate.googleapis.com/translate_a/single?client=gtx&sl="
+ "en" + "&tl=" + "iw" + "&dt=t&q=" + encodeURI(text);
var result = JSON.parse(UrlFetchApp.fetch(urllog).getContentText());
translatedText = result[0][0][0];
console.log(translatedText);
}
so the url is downloading me a text file called "f.txt" that include the translate code the problem is that I doesnt want it to download File,
I just need the translate inside the txt file its gives me,
also the problem is I am not sure how to get that info inside a javascript variable, And I doesnt want it to give me that file as well..
So how Can I read it?
how can I use the file without download it, and How can I push it to a string variable?
And How I can cancel the download and get only the translate?
THANKS!
By the way
and if anyone know the function doGet(e) that I showed on the link, what is "e"? what does the function wants?
I know I'm a year late but I came to same problem and fixed it using PHP. I have created this simple PHP function:
function translate($text, $from, $to) {
if($text == null)
echo "Please enter a text to translate.";
if($from == null)
$from = "auto";
if($to == null)
$to = "en";
$NEW_TEXT = preg_replace('/\s+/', '+', $text);
$API_URL = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" . $from . "&tl=" . $to . "&dt=t&q=" . $NEW_TEXT;
$OUTPUT = get_remote_data($API_URL);
$json = json_decode($OUTPUT, true); // decode the JSON into an associative array
$TRANSLATED_OUTPUT = $json[0][0][0];
echo $TRANSLATED_OUTPUT;
}
Example usage (English to Spanish):
translate("Hello", "en", "es"); //Output: Hola
/*
sourceLanguage: the 2-3 letter language code of the source language (English = "en")
targetLanguage: the 2-3 letter language code of the target language (Hebrew is "iw")
text: the text to translate
callback: the function to call once the request finishes*
* Javascript is much different from C# in that it is an asynchronous language, which
means it works on a system of events, where anything may happen at any time
(which makes sense when dealing with things on the web like sending requests to a
server). Because of this, Javascript allows you to pass entire
functions as parameters to other functions (called callbacks) that trigger when some
time-based event triggers. In this case, as seen below,
we use our callback function when the request to google translate finishes.
*/
const translate = function(sourceLanguage,targetLanguage,text,callback) {
// make a new HTTP request
const request = new XMLHttpRequest();
/*
when the request finishes, call the specified callback function with the
response data
*/
request.onload = function() {
// using JSON.parse to turn response text into a JSON object
callback(JSON.parse(request.responseText));
}
/*
set up HTTP GET request to translate.googleapis.com with the specified language
and translation text parameters
*/
request.open(
"GET",
"https://translate.googleapis.com/translate_a/single?client=gtx&sl=" +
sourceLanguage + "&tl=" + targetLanguage + "&dt=t&q=" + text,
true
);
// send the request
request.send();
}
/*
translate "This shouldn't download anything" from English to Hebrew
(when the request finishes, it will follow request.onload (specified above) and
call the anonymous
function we use below with the request response text)
*/
translate("en","iw","This shouldn't download anything!",function(translation) {
// output google's JSON object with the translation to the console
console.log(translation);
});
I am new to office 365 word JavaScript API. I am trying to send a Json object to a dialog from the parent using the dialog api. But I couldn't find a better solution for that. I have found it is possible to send a Json object from the dialog to the parent using below code snippet.
Office.context.ui.messageParent
can someone give me a good solution with a code snippet to solve this problem?
You can try something like that
In parent web page (the actual add-in) javascript code
Office.context.ui.displayDialogAsync(url, options, function(result) {
var dialog = result.value;
dialog.addEventHandler(Office.EventType.DialogMessageReceived, function(args){
dialog.close();
var json = JSON.parse(args.message);
//do what ever you need to do...
});
});
NOTE: for the sake of simplicity I omitted "error checks" if callback function receive error result. You should take care of that as well.
The web page that is opened at url will have a function for pushing back the json object after representing it as a string
var asString = JSON.stringify(myObj);
Office.context.ui.messageParent(asString);
Of course the webpage opened in the dialog window must also reference Office.js.
Here is the documentation link for this so-called dialogAPI https://dev.office.com/reference/add-ins/shared/officeui
Edit:
the original question is to send data from parent to children
If you need to send info to the page opened in dialogAPI. I suggest your append query parameters to url. You can stringify your Json object and pass it. This is not very clean thought.
Standardized way to serialize JSON to query string?
You can send JSON data or object back to your parent easily.
This code snippet should be in your child page's(Dialog page) JS file.
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
$('#btnLogin').click(submit);
});
};
function submit() {
// Get and create the data object.
var email = $('#txtEmail').val();
var password = $('#txtPassword').val();
var data = {
email: email,
password: password
}
// Create the JSON and send it to the parent.
var json = JSON.stringify(data);
Office.context.ui.messageParent("json");
}
})();
See here: https://dev.office.com/docs/add-ins/develop/dialog-api-in-office-add-ins
Find section "Passing information to the dialog box".
Two primary ways:
Add query parameters to the URL
Store the information somewhere that is accessible to both the host window and dialog box, e.g. local storage
Our corporate wiki is Mediawiki. I have no problem to put iframe into my site to refer for some article on wiki.
But my own site have a lot of widgets and own style. I don't want to include Mediawiki navigation/search/login widgets, logo image.
Is it possible and how to get Mediawiki page contents without widgets (only article body)?
Yes, it is. You'll probably want to use the action=render url parameter, for example: http://en.wikipedia.org/w/index.php?action=render&title=Main_Page. Note that the stylesheets from the wiki aren't included, so you'll need to copy the relevant rules to your site's css files. See also this.
Thank waldir for answer!
After asking question I perform own research and end with code:
window.onload = function() {
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState !== 4) {
console.log("Not ready, code: %o", httpRequest.readyState);
return;
}
if (httpRequest.status !== 200) {
console.log("Server error: %o", httpRequest.status);
return;
}
var json = JSON.parse(httpRequest.responseText);
console.log("json: %o", json);
var wiki = json.query.pages["1"].revisions[0]["*"];
console.log("wiki: %o", wiki);
var html = InstaView.convert(wiki);
console.log("html: %o", html);
document.getElementById('area').innerHTML = html;
};
var url = 'https://wiki.evil-company.com/api.php?action=query&prop=revisions&format=json&titles=Main_page&rvprop=timestamp|user|comment|content';
httpRequest.open('GET', url, true);
httpRequest.send(null);
}
Here I use https://github.com/cscott/instaview/blob/master/main.js project which is enhanced http://en.wikipedia.org/wiki/User:Pilaf to transform json output to HTML on browser side.
The reason for this code because our wiki is old or misconfigured and action=render is not available. But I trap into cross-domain scripting issue so I think that iframe with action=render is better solution.
See also How do you grab an article including the links in a usable format?
Another suggestion to use action=parse (http://en.wikipedia.org/w/api.php?action=parse&title=Linux) lead to warning:
You are looking at the HTML representation of the XML format.
HTML is good for debugging, but is unsuitable for application use.
Specify the format parameter to change the output format.
UPDATE
Perfect solution just append query action=render to any valid wiki URL like:
http://en.wikipedia.org/wiki/Linux?action=render
I am building a Chrome Extension and I have a requirement to overlay a blob of html on top of a few websites. At the moment I am using a JQuery .Get to pull the html from my server. In order to improve performance I am wondering if it is possible to include the html as a file in the extension directory and access the source directly from there? Does anyone know if this is possible?
UPDATE
Rob's suggestion does the job (see accepted answer). The only additional step is to register the file in the manifest under web_accessible_resources.
{
...
"web_accessible_resources": [
"myimportfile1.html",
"myimportfile2.html"
],
...
}
Yes, that's possible. Use chrome.runtime.getURL to get an absolute URL for the resource. For example:
Step 1 (standard JavaScript):
fetch(chrome.runtime.getURL('/template.html')).then(r => r.text()).then(html => {
document.body.insertAdjacentHTML('beforeend', html);
// not using innerHTML as it would break js event listeners of the page
});
Step 1 (jQuery):
$.get(chrome.runtime.getURL('/template.html'), function(data) {
$(data).appendTo('body');
// Or if you're using jQuery 1.8+:
// $($.parseHTML(data)).appendTo('body');
});
Step 2:
Register the resource in the manifest.json under web_accessible_resources:
"web_accessible_resources": [
"template.html",
"foo.jpg"
]
Another way of doing it is to use new Fetch API:
If the file's name is modal.html - update manifest.json accordingly
"web_accessible_resources": [
"modal.html",
],
and inject it like this:
fetch(chrome.runtime.getURL('/modal.html'))
.then(response => response.text())
.then(data => {
document.getElementById('inject-container').innerHTML = data;
// other code
// eg update injected elements,
// add event listeners or logic to connect to other parts of the app
}).catch(err => {
// handle error
});
This is my approach using a synchronous XHR:
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", chrome.runtime.getURL ("src/inject/inject.html"), false );
xmlHttp.send( null );
var inject = document.createElement("div");
inject.innerHTML = xmlHttp.responseText
document.body.insertBefore (inject, document.body.firstChild);
Without jQuery etc.
I use this code. It's only 3 lines of code and you don't need any jquery's garbage.
var iframe = document.createElement ('iframe');
iframe.src = chrome.runtime.getURL ('iframe.html');
document.body.appendChild (iframe);
If you're using Angular in your Chrome extension, you can make use of ng-include
var injectedContent = document.createElement("div");
injectedContent.setAttribute("ng-include", "");
//ng-include src value must be wrapped in single quotes
injectedContent.setAttribute("src", "'" + chrome.runtime.getURL("template.html") + "'");
existingElement.appendChild(injectedContent);
I need to do a cross-domain request in a chrome extension. I know I can it via message passing but I'd rather stick to just jQuery idioms (so my javascript can also work as a <script src="">).
I do the normal:
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function(data) {
console.log(data);
});
but in the error console I see:
Uncaught ReferenceError: jsonp1271044791817 is not defined
Is jQuery not inserting the callback function correctly into the document? What can I do to make this work?
(If I paste the code into a chrome console, it works fine, but if I put it as the page.js in an extension is when the problem appears.)
Alas, none of these worked, so I ended up doing the communication via the background.html.
background.html
<script src="http://code.jquery.com/jquery-1.4.2.js"></script>
<script>
function onRequest(request, sender, callback) {
if (request.action == 'getJSON') {
$.getJSON(request.url, callback);
}
}
chrome.extension.onRequest.addListener(onRequest);
</script>
javascripts/page.js
chrome_getJSON = function(url, callback) {
console.log("sending RPC");
chrome.extension.sendRequest({action:'getJSON',url:url}, callback);
}
$(function(){
// use chrome_getJSON instead of $.getJSON
});
If you specify "api.flickr.com" in your manifest.json file you will not need to use the JSONP callback, script injection style of cross domain request.
For example:
"permissions": ["http://api.flickr.com"],
This should work beautifully in you code. I would remove the querystring parameter "&jsoncallback" as there is no JSONP work needed.
The reason why your current code is not working is your code is injecting into pages DOM, content scripts have access to the DOM but no access to javascript context, so there is no method to call on callback.
My impressions it that this fails because the jQuery callback function is being created within the 'isolated world' of the Chrome extension and is inaccessible when the response comes back:
http://code.google.com/chrome/extensions/content_scripts.html#execution-environment
I'm using Prototype and jQuery for various reasons, but my quick fix should be easy to parse:
// Add the callback function to the page
s = new Element('script').update("function boom(e){console.log(e);}");
$$('body')[0].insert(s);
// Tell jQuery which method to call in the response
function shrink_link(oldLink, callback){
jQuery.ajax({
type: "POST",
url: "http://api.awe.sm/url.json",
data: {
v: 3,
url: oldLink,
key: "5c8b1a212434c2153c2f2c2f2c765a36140add243bf6eae876345f8fd11045d9",
tool: "mKU7uN",
channel: "twitter"
},
dataType: "jsonp",
jsonpCallback: callback
});
}
// And make it so.
shrink_link('http://www.google.com', "boom");
Alternatively you can try using the extension XHR capability:
http://code.google.com/chrome/extensions/xhr.html
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();
The syntax is a little off. There's no need for the callback( bit. This works flawlessly. Tested in the javascript console of Chrome on this StackOverflow page (which includes jQuery):
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function(data) {
console.log(data);
});
As many of you will know, Google Chrome doesn't support any of the handy GM_ functions at the moment.
As such, it is impossible to do cross site AJAX requests due to various sandbox restrictions (even using great tools like James Padolsey's Cross Domain Request Script)
I needed a way for users to know when my Greasemonkey script had been updated in Chrome (since Chrome doesn't do that either...). I came up with a solution which is documented here (and in use in my Lighthouse++ script) and worth a read for those of you wanting to version check your scripts:
http://blog.bandit.co.nz/post/1048347342/version-check-chrome-greasemonkey-script