Google's "Report a Bug" or "Feedback Tool" lets you select an area of your browser window to create a screenshot that is submitted with your feedback about a bug.
Screenshot by Jason Small, posted in a duplicate question.
How are they doing this? Google's JavaScript feedback API is loaded from here and their overview of the feedback module will demonstrate the screenshot capability.
JavaScript can read the DOM and render a fairly accurate representation of that using canvas. I have been working on a script which converts HTML into a canvas image. Decided today to make an implementation of it into sending feedbacks like you described.
The script allows you to create feedback forms which include a screenshot, created on the client's browser, along with the form. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
It does not require any rendering from the server, as the whole image is created on the client's browser. The HTML2Canvas script itself is still in a very experimental state, as it does not parse nearly as much of the CSS3 attributes I would want it to, nor does it have any support to load CORS images even if a proxy was available.
Still quite limited browser compatibility (not because more couldn't be supported, just haven't had time to make it more cross browser supported).
For more information, have a look at the examples here:
http://hertzen.com/experiments/jsfeedback/
edit
The html2canvas script is now available separately here and some examples here.
edit 2
Another confirmation that Google uses a very similar method (in fact, based on the documentation, the only major difference is their async method of traversing/drawing) can be found in this presentation by Elliott Sprehn from the Google Feedback team:
http://www.elliottsprehn.com/preso/fluentconf/
Your web app can now take a 'native' screenshot of the client's entire desktop using getUserMedia():
Have a look at this example:
https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/
The client will have to be using chrome (for now) and will need to enable screen capture support under chrome://flags.
PoC
As Niklas mentioned you can use the html2canvas library to take a screenshot using JS in the browser. I will extend his answer in this point by providing an example of taking a screenshot using this library ("Proof of Concept"):
function report() {
let region = document.querySelector("body"); // whole screen
html2canvas(region, {
onrendered: function(canvas) {
let pngUrl = canvas.toDataURL(); // png in dataURL format
let img = document.querySelector(".screen");
img.src = pngUrl;
// here you can allow user to set bug-region
// and send it with 'pngUrl' to server
},
});
}
.container {
margin-top: 10px;
border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div>Screenshot tester</div>
<button onclick="report()">Take screenshot</button>
<div class="container">
<img width="75%" class="screen">
</div>
In report() function in onrendered after getting image as data URI you can show it to the user and allow him to draw "bug region" by mouse and then send a screenshot and region coordinates to the server.
In this example async/await version was made: with nice makeScreenshot() function.
UPDATE
Simple example which allows you to take screenshot, select region, describe bug and send POST request (here jsfiddle) (the main function is report()).
async function report() {
let screenshot = await makeScreenshot(); // png dataUrl
let img = q(".screen");
img.src = screenshot;
let c = q(".bug-container");
c.classList.remove('hide')
let box = await getBox();
c.classList.add('hide');
send(screenshot,box); // sed post request with bug image, region and description
alert('To see POST requset with image go to: chrome console > network tab');
}
// ----- Helper functions
let q = s => document.querySelector(s); // query selector helper
window.report = report; // bind report be visible in fiddle html
async function makeScreenshot(selector="body")
{
return new Promise((resolve, reject) => {
let node = document.querySelector(selector);
html2canvas(node, { onrendered: (canvas) => {
let pngUrl = canvas.toDataURL();
resolve(pngUrl);
}});
});
}
async function getBox(box) {
return new Promise((resolve, reject) => {
let b = q(".bug");
let r = q(".region");
let scr = q(".screen");
let send = q(".send");
let start=0;
let sx,sy,ex,ey=-1;
r.style.width=0;
r.style.height=0;
let drawBox= () => {
r.style.left = (ex > 0 ? sx : sx+ex ) +'px';
r.style.top = (ey > 0 ? sy : sy+ey) +'px';
r.style.width = Math.abs(ex) +'px';
r.style.height = Math.abs(ey) +'px';
}
//console.log({b,r, scr});
b.addEventListener("click", e=>{
if(start==0) {
sx=e.pageX;
sy=e.pageY;
ex=0;
ey=0;
drawBox();
}
start=(start+1)%3;
});
b.addEventListener("mousemove", e=>{
//console.log(e)
if(start==1) {
ex=e.pageX-sx;
ey=e.pageY-sy
drawBox();
}
});
send.addEventListener("click", e=>{
start=0;
let a=100/75 //zoom out img 75%
resolve({
x:Math.floor(((ex > 0 ? sx : sx+ex )-scr.offsetLeft)*a),
y:Math.floor(((ey > 0 ? sy : sy+ey )-b.offsetTop)*a),
width:Math.floor(Math.abs(ex)*a),
height:Math.floor(Math.abs(ex)*a),
desc: q('.bug-desc').value
});
});
});
}
function send(image,box) {
let formData = new FormData();
let req = new XMLHttpRequest();
formData.append("box", JSON.stringify(box));
formData.append("screenshot", image);
req.open("POST", '/upload/screenshot');
req.send(formData);
}
.bug-container { background: rgb(255,0,0,0.1); margin-top:20px; text-align: center; }
.send { border-radius:5px; padding:10px; background: green; cursor: pointer; }
.region { position: absolute; background: rgba(255,0,0,0.4); }
.example { height: 100px; background: yellow; }
.bug { margin-top: 10px; cursor: crosshair; }
.hide { display: none; }
.screen { pointer-events: none }
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<body>
<div>Screenshot tester</div>
<button onclick="report()">Report bug</button>
<div class="example">Lorem ipsum</div>
<div class="bug-container hide">
<div>Select bug region: click once - move mouse - click again</div>
<div class="bug">
<img width="75%" class="screen" >
<div class="region"></div>
</div>
<div>
<textarea class="bug-desc">Describe bug here...</textarea>
</div>
<div class="send">SEND BUG</div>
</div>
</body>
Get screenshot as Canvas or Jpeg Blob / ArrayBuffer using getDisplayMedia API:
FIX 1: Use the getUserMedia with chromeMediaSource only for Electron.js
FIX 2: Throw error instead return null object
FIX 3: Fix demo to prevent the error: getDisplayMedia must be called from a user gesture handler
// docs: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia
// see: https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/#20893521368186473
// see: https://github.com/muaz-khan/WebRTC-Experiment/blob/master/Pluginfree-Screen-Sharing/conference.js
function getDisplayMedia(options) {
if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
return navigator.mediaDevices.getDisplayMedia(options)
}
if (navigator.getDisplayMedia) {
return navigator.getDisplayMedia(options)
}
if (navigator.webkitGetDisplayMedia) {
return navigator.webkitGetDisplayMedia(options)
}
if (navigator.mozGetDisplayMedia) {
return navigator.mozGetDisplayMedia(options)
}
throw new Error('getDisplayMedia is not defined')
}
function getUserMedia(options) {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
return navigator.mediaDevices.getUserMedia(options)
}
if (navigator.getUserMedia) {
return navigator.getUserMedia(options)
}
if (navigator.webkitGetUserMedia) {
return navigator.webkitGetUserMedia(options)
}
if (navigator.mozGetUserMedia) {
return navigator.mozGetUserMedia(options)
}
throw new Error('getUserMedia is not defined')
}
async function takeScreenshotStream() {
// see: https://developer.mozilla.org/en-US/docs/Web/API/Window/screen
const width = screen.width * (window.devicePixelRatio || 1)
const height = screen.height * (window.devicePixelRatio || 1)
const errors = []
let stream
try {
stream = await getDisplayMedia({
audio: false,
// see: https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints/video
video: {
width,
height,
frameRate: 1,
},
})
} catch (ex) {
errors.push(ex)
}
// for electron js
if (navigator.userAgent.indexOf('Electron') >= 0) {
try {
stream = await getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
// chromeMediaSourceId: source.id,
minWidth : width,
maxWidth : width,
minHeight : height,
maxHeight : height,
},
},
})
} catch (ex) {
errors.push(ex)
}
}
if (errors.length) {
console.debug(...errors)
if (!stream) {
throw errors[errors.length - 1]
}
}
return stream
}
async function takeScreenshotCanvas() {
const stream = await takeScreenshotStream()
// from: https://stackoverflow.com/a/57665309/5221762
const video = document.createElement('video')
const result = await new Promise((resolve, reject) => {
video.onloadedmetadata = () => {
video.play()
video.pause()
// from: https://github.com/kasprownik/electron-screencapture/blob/master/index.js
const canvas = document.createElement('canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
const context = canvas.getContext('2d')
// see: https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight)
resolve(canvas)
}
video.srcObject = stream
})
stream.getTracks().forEach(function (track) {
track.stop()
})
if (result == null) {
throw new Error('Cannot take canvas screenshot')
}
return result
}
// from: https://stackoverflow.com/a/46182044/5221762
function getJpegBlob(canvas) {
return new Promise((resolve, reject) => {
// docs: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
canvas.toBlob(blob => resolve(blob), 'image/jpeg', 0.95)
})
}
async function getJpegBytes(canvas) {
const blob = await getJpegBlob(canvas)
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.addEventListener('loadend', function () {
if (this.error) {
reject(this.error)
return
}
resolve(this.result)
})
fileReader.readAsArrayBuffer(blob)
})
}
async function takeScreenshotJpegBlob() {
const canvas = await takeScreenshotCanvas()
return getJpegBlob(canvas)
}
async function takeScreenshotJpegBytes() {
const canvas = await takeScreenshotCanvas()
return getJpegBytes(canvas)
}
function blobToCanvas(blob, maxWidth, maxHeight) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = function () {
const canvas = document.createElement('canvas')
const scale = Math.min(
1,
maxWidth ? maxWidth / img.width : 1,
maxHeight ? maxHeight / img.height : 1,
)
canvas.width = img.width * scale
canvas.height = img.height * scale
const ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height)
resolve(canvas)
}
img.onerror = () => {
reject(new Error('Error load blob to Image'))
}
img.src = URL.createObjectURL(blob)
})
}
DEMO:
document.body.onclick = async () => {
// take the screenshot
var screenshotJpegBlob = await takeScreenshotJpegBlob()
// show preview with max size 300 x 300 px
var previewCanvas = await blobToCanvas(screenshotJpegBlob, 300, 300)
previewCanvas.style.position = 'fixed'
document.body.appendChild(previewCanvas)
// send it to the server
var formdata = new FormData()
formdata.append("screenshot", screenshotJpegBlob)
await fetch('https://your-web-site.com/', {
method: 'POST',
body: formdata,
'Content-Type' : "multipart/form-data",
})
}
// and click on the page
Here is a complete screenshot example that works with chrome in 2021. The end result is a blob ready to be transmitted. Flow is: request media > grab frame > draw to canvas > transfer to blob. If you want to do it more memory efficient explore OffscreenCanvas or possibly ImageBitmapRenderingContext
https://jsfiddle.net/v24hyd3q/1/
// Request media
navigator.mediaDevices.getDisplayMedia().then(stream =>
{
// Grab frame from stream
let track = stream.getVideoTracks()[0];
let capture = new ImageCapture(track);
capture.grabFrame().then(bitmap =>
{
// Stop sharing
track.stop();
// Draw the bitmap to canvas
canvas.width = bitmap.width;
canvas.height = bitmap.height;
canvas.getContext('2d').drawImage(bitmap, 0, 0);
// Grab blob from canvas
canvas.toBlob(blob => {
// Do things with blob here
console.log('output blob:', blob);
});
});
})
.catch(e => console.log(e));
Heres an example using: getDisplayMedia
document.body.innerHTML = '<video style="width: 100%; height: 100%; border: 1px black solid;"/>';
navigator.mediaDevices.getDisplayMedia()
.then( mediaStream => {
const video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = e => {
video.play();
video.pause();
};
})
.catch( err => console.log(`${err.name}: ${err.message}`));
Also worth checking out is the Screen Capture API docs.
You can try my new JS library: screenshot.js.
It's enable to take real screenshot.
You load the script:
<script src="https://raw.githubusercontent.com/amiad/screenshot.js/master/screenshot.js"></script>
and take screenshot:
new Screenshot({success: img => {
// callback function
myimage = img;
}});
You can read more options in project page.
Related
We created a rest API on python and it is locally running. And the 'http://127.0.0.1:5002/business' API is showing contents {"business name": "something"} if I open it on google chrome. However, when we call this API in nodejs, it always gives me the error. But if I use another API(exactly same code but different api in nodejs), it is working.
async function get_recommend_initial(){
//https://ViolaS.api.stdlib.com/InitialRecommendation#dev/
// // agent.add('providing recommendations...');
const options = {
method: 'GET'
,uri: 'http://127.0.0.1:5002/business'
// ,uri:'https://ViolaS.api.stdlib.com/InitialRecommendation#dev/'
// ,json: true
};
// return request(options).then(response => {
// console.log(response)
// return (response)
// }).catch(function (err) {
// console.log('No recommend data');
// console.log(err);
// });
return requestAPI(options).then(function(data)
{
let initial_recommendation = JSON.parse(data);
console.log(initial_recommendation);
//return initial_recommendation.information[0].name;
}).catch(function (err) {
console.log('No recommend data');
console.log(err);
});
}
1
The API that is created by python file which is running locally. You can see the API code figure by moving your mouth above 1. Thanks!!!
The python code is as follows:
app = Flask(__name__)
#Add resources to be much cleaner
api = Api(app)
features = {}
class Business(Resource):
def get(self):
return {'business name': 'something'} # Fetches first column that is Employee ID
def post(self):
some_json = request.get_json()
print(some_json)
countNumber = features.get('count',0) + 1
features['count'] = countNumber
return {'You sent': some_json,
'Count:':countNumber}, 201
def put(self):
some_json = request.get_json()
print(some_json)
#record the count number
countNumber = features.get('count',0) + 1
features['count'] = countNumber
features['ok'] = 'yes'
return {'You sent': some_json,
'Count:':countNumber,
'Ok:': features['ok']}, 201
api.add_resource(Business, '/business') # Route_1
if __name__ == '__main__':
app.run(port='5002')
The error is as following:
dialogflowFirebaseFulfillment
Error: Unknown response type: "undefined" at WebhookClient.addResponse_ (/srv/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:277:13) at WebhookClient.add (/srv/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:245:12) at Sys_Recommend (/srv/index.js:31:11) at <anonymous>
And the log is:
No recommend data
I'm looking for a Play Framework pagination example. Please help me with a good reference link.
I searched for it and don't have java code.
I'll provide a Scala solution and you can adjust your code.
You could create a utility class called Paginator:
package util
case class Paginator[A](items: Seq[A], page: Int, offset: Long, total: Long) {
lazy private val pageSize: Int = 20 // you can adjust to your preference
lazy val prevPage: Option[Int] = Option(page - 1).filter(_ >= 0)
lazy val nextPage: Option[Int] = Option(page + 1).filter(_ => (offset + items.size) < total)
lazy val numberOfPages: Float = if (total % pageSize > 0) { total / pageSize + 1 }
else { total / pageSize }
}
In your controller you will do something like:
def list(currentPage: Int) = Action.async { implicit request =>
val offset: Int = currentPage * resultsPerPage
// Put your logic here to get the `listOfItems` you want to display
// and the number of `totalItems`
// and then return Ok and call your view
Ok(views.html.list(Paginator(listOfItems, currentPage, offset, totalItems)))
}
and finally in your view you will have something like:
#import util.Paginator
#(paginatedList: Paginator[Item])(implicit msg: play.api.i18n.MessagesProvider)
#main(msg.messages("label.list_of_items")) {
<h1>#msg.messages("label.paginated_list")</h1>
#* populate your list here *#
#* and this is your paginator *#
<div class="pagination">
#paginatedList.prevPage.map { page =>
<a href="#link(page)">#msg.messages("label.previous")<a>
}.get
#for(pageNumber <- 1 to paginatedList.numberOfPages.toInt) {
#pageNumber
}
#paginatedList.nextPage.map { page =>
#msg.messages("label.next")
}.get
</div>
}
I got the original idea from this project and I've expanded on it. You can also improve the paginator by using getOrElse to provide alternative/disabled links when being on the first/last page, or to disable the current page number etc.
I hope this helps.
I added flow.js in my proyect following the instructions and the call to my java servlet:
localhost:8080/WebExample/UploadImgServlet?flowChunkNumber=1&flowChunkSize=1048576&flowCurrentChunkSize=693916&flowTotalSize=693916&flowIdentifier=693916-image2png&flowFilename=image2.png&flowRelativePath=image2.png&flowTotalChunks=1`
In my servlet I get all parameters of the url (flowChuckNumber, flowChuckSize, etc) but when I try to get the file (request.getInputStream()), it's empty and upload 0 bytes.
Where is the problem? Any Idea?
I found a similar question but it was with PHP...
My code:
HTML(the image is displayed):
...
...
<div flow-init="{singleFile:true}"
flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]"
flow-files-submitted="$flow.upload()"
flow-file-success="$file.msg = $message">
<div class="drop" flow-drop ng-class="dropClass">
<md-button class="md-raised md-primary" type="file" flow-btn>Upload Image</md-button>
<b>OR</b>
Drag And Drop your image here
</div>
<div class="thumbnail" ng-show="!$flow.files.length">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt="Image"/>
</div>
<div class="thumbnail" ng-show="$flow.files.length">
<img flow-img="$flow.files[0]" />
</div>
<table>
<tr ng-repeat="file in $flow.files">
<td>{{$index+1}}</td>
<td>{{file.name}}</td>
<td>{{file.msg}}</td>
</tr>
</table>
</div>
...
...
App AngularJs:
var app = angular.module("webexample", ['ngMaterial', 'ngNotify','uiGmapgoogle-maps','flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
flowFactoryProvider.defaults = {
target: '/WebExample/UploadImgServlet',
permanentErrors: [404, 500, 501],
maxChunkRetries: 1,
chunkRetryInterval: 5000,
simultaneousUploads: 1
};
flowFactoryProvider.on('catchAll', function (event) {
console.log('catchAll', arguments);
});
// Can be used with different implementations of Flow.js
// flowFactoryProvider.factory = fustyFlowFactory;
}])
.directive('appDownloadUrl', [function () {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('dragstart', function (event) {
var config = scope.$eval(attrs.appDownloadUrl);
if (!config.disabled) {
var data = config.mime + ':' + config.name + ':' + window.location.href + config.url;
console.log("data: "+data);
event.dataTransfer.setData('DownloadURL', data);
}
});
}
};
}])
.directive("appDragstart", [function () {
return function(scope, element, attrs) {
element.bind('dragstart', function (event) {
scope.$eval(attrs.appDragstart);
});
}
}]).directive("appDragend", [function () {
return function(scope, element, attrs) {
element.bind('dragend', function (event) {
scope.$eval(attrs.appDragend);
});
}
}]).run(function ($rootScope) {
$rootScope.dropEnabled = true;
});
My Servlet (I followed this example):
protected void doService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
LOGGER.debug("[UploadImgServlet - doService] - init");
int resumableChunkNumber = getResumableChunkNumber(request);
ResumableInfo info = getResumableInfo(request);
//info contains all flow parameters of the url.
RandomAccessFile raf = new RandomAccessFile(info.resumableFilePath, "rw");
//Seek to position
raf.seek((resumableChunkNumber - 1) * info.resumableChunkSize);
//Save to file
InputStream is = request.getInputStream();
long readed = 0;
long content_length = request.getContentLength();
//**PROBLEM: request.getContentLength return -1 so read 0 bytes**
byte[] bytes = new byte[1024 * 100];
while(readed < content_length) {
int r = is.read(bytes);
if (r < 0) {
break;
}
raf.write(bytes, 0, r);
readed += r;
}
raf.close();
...
...
The input stream will be empty because flowjs posts the content using MultiPart by default.
The author of the Java code specified that "Octet" should be used for uploads, not multi-part.
UploadServlet accepts Resumable.js Upload with 'octet'
You need to add "method:octet" to your init,
<div flow-init="{singleFile:true, method:octet}"
I am using Spring, so I just used MultipartHttpServletRequest to get the posted data with MultiPart instead because MultiPart is more common.
This is how I received the contents of the file:
Iterator<String> itr = request.getFileNames();
/* Iterate each file, there should only be one/one chunk */
while (itr.hasNext()) {
fileUploaded = request.getFile(itr.next());
raf.write(fileUploaded.getBytes());
}
raf.close();
I had to do more fixes to the java code provided because it was estimating the number of chunks to receive wrong, so I just used the "flowTotalChunks" parameter.
You don't need to worry about content length. The HttpServletRequest will terminate the input stream at the correct point. Just read until end of stream.
I wanted a lib to upload images with more options and visually appealing (drop file from a folder, thumbnail, etc) than the default html input and I have not been able to do with Flowjs and Java Servlet, so I looked for another lib:
https://github.com/danialfarid/ng-file-upload
https://angular-file-upload.appspot.com/
With this lib, I found it easy to use with Java Servlet.
I don't mark this post as solved for if someone finds a way to do it with Flowjs.
within a web page is a script that allows you to see a video and other.
using python and selenium can not be run the script after the mouse clicks. Of the currently am using this code:
videoGemPath = ".//*[#id='brandconnect']/a/img"
scriptPath = ".//*[#id='content']/script"
elementScript = "/html/body/div[2]/div[1]"
location = driver.find_element_by_xpath(scriptPath)
ActionChains(driver).move_to_element(location).click().perform()
but it returns this error
=========================================================================
Traceback (most recent call last):
File "C:\Users\xxxxxx\Desktop\Proggetti VB\Per Web\PythonApplication4\PythonApplication4\PythonApplication4.py", line 66, in test_Login
ActionChains(driver).move_to_element(location).click().perform()
File "C:\Python27\lib\site-packages\selenium-2.48.0-py2.7.egg\selenium\webdriver\common\action_chains.py", line 72, in perform
action()
File "C:\Python27\lib\site-packages\selenium-2.48.0-py2.7.egg\selenium\webdriver\common\action_chains.py", line 217, in
self._driver.execute(Command.MOVE_TO, {'element': to_element.id}))
File "C:\Python27\lib\site-packages\selenium-2.48.0-py2.7.egg\selenium\webdriver\remote\webdriver.py", line 201, in execute
self.error_handler.check_response(response)
File "C:\Python27\lib\site-packages\selenium-2.48.0-py2.7.egg\selenium\webdriver\remote\errorhandler.py", line 181, in check_response
raise exception_class(message, screen, stacktrace)
MoveTargetOutOfBoundsException: Message: Offset within element cannot be scrolled into view: (352.5, 241.5): [object HTMLScriptElement]
Stacktrace:
at FirefoxDriver.prototype.mouseMoveTo (file:///c:/users/xxxxxx/appdata/local/temp/tmpgnvb0k/extensions/fxdriver#googlecode.com/components/driver-component.js:10961)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/xxxxxx/appdata/local/temp/tmpgnvb0k/extensions/fxdriver#googlecode.com/components/command-processor.js:12534)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/xxxxxx/appdata/local/temp/tmpgnvb0k/extensions/fxdriver#googlecode.com/components/command-processor.js:12539)
at DelayedCommand.prototype.execute/< (file:///c:/users/xxxxxxx/appdata/local/temp/tmpgnvb0k/extensions/fxdriver#googlecode.com/components/command-processor.js:12481)
=========================================================================
the script code is this:
// create button
document.write('<div id="brandconnect"><img src="img/bconnect_area.png" class="tooltip" rel="Guarda video e ricevi Gemme gratis!" alt="" /></div>');
// ini local storage to save last button state if this html5 feature is available
var storage = false;
try {
if( window && window.localStorage ) {
storage = window.localStorage;
if( typeof(storage.bcVisible) === 'string' ) {
if( storage.bcVisible == 'true' ) {
showBC();
}
else {
hideBC();
}
}
}
}
catch( ignore ) {
// local storage might require user approval. in this case we don't use it
}
// handle button visibility
function handleBC(obj) {
if( typeof(obj) != 'object' || obj.length < 1 ) {
// no videos available
hideBC();
}
else {
// videos are available
showBC();
}
}
// show brandconnect button
function showBC() {
clink = document.getElementById('brandconnect');
if( clink ) {
clink.style.display = 'block';
}
if( storage ) {
storage.bcVisible = 'true';
}
}
// hide brandconnect button
function hideBC() {
document.getElementById('brandconnect').style.display = 'none';
if( storage ) {
storage.bcVisible = 'false';
}
}
function hoverBC() {
document.getElementById('brandconnect').style.backgroundPosition = '-89px 0';
}
function unhoverBC() {
document.getElementById('brandconnect').style.backgroundPosition = '0 0';
}
// definitions by JSON
var ssa_json = {
'applicationUserId': '512000516',
'applicationKey': '2ae25b1d',
'currencyName': 'Gemme',
'onCampaignsReady': handleBC,
'onCampaignsDone': hideBC,
'onCampaignCompleted': handleBC,
'onCampaignClose': handleBC
};
// embed supersonic script
(function(d,t){
var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.async = true;
g.src = ('https:' != location.protocol ? 'http://jsd.supersonicads.com' :
'https://supersonicads.cotssl.net') + '/inlineDelivery/delivery.min.gz.js';
s.parentNode.insertBefore(g,s);
}(document,'script'));
//]]>
How can I fix it?
I need to run my javascript function periodically on server starts. i dont know how to write the equivalent Java code as my javaScript function contains multiple ajax call and mathematical equations.
below is my javascript code which i need to run periodically on server start.
<script type="text/javascript">
$(document).ready(function(){
var polyLat = new Array();
polyLat[0] = 10.194027;
polyLat[1] = 10.226975;
polyLat[2] = 10.059987;
polyLat[3] = 10.002248;
polyLat[4] = 9.854925;
polyLat[5] = 9.835443;
polyLat[6] = 9.899107;
polyLat[7] = 9.993088;
polyLat[8] = 10.081425;
polyLat[9] = 9.992266;
polyLat[10] = 10.194027;//First point repeated to close polygon
var polySides = (polyLat.length)-1;//number of points in polygon
//vertical Longitude coordinates of polygon
var polyLng = new Array();
polyLng[0] = 76.201205;
polyLng[1] = 76.375022;
polyLng[2] = 76.775730;
polyLng[3] = 76.778940;
polyLng[4] = 76.584336;
polyLng[5] = 76.411473;
polyLng[6] = 76.368070;
polyLng[7] = 76.397007;
polyLng[8] = 76.317492;
polyLng[9] = 76.267905;
polyLng[10] = 76.201205;//First point repeated to close polygon
//Coordinates for bounding box
var maxLat = Math.max.apply(null,polyLat);
var minLat = Math.min.apply(null,polyLat);
var maxLng = Math.max.apply(null,polyLng);
var minLng = Math.min.apply(null,polyLng);
$.post('outboundupd.jsp',
{
mx_lat:maxLat,
mn_lat:minLat,
mx_lng:maxLng,
mn_lng:minLng,
ply_sds:polySides
},
function(response,status,xhr)
{
// alert(response.trim());
plotdata(response);
});
function plotdata(response)
{
var x;
var y;
var mob;
var jsonArray=JSON.parse(response.trim());
var jalen= jsonArray.length;
for(i=0;i<jalen;i++)
{
var obj=jsonArray[i];
pcode= obj.Pcode;
nplate= obj.N_plate;
driver= obj.Driver;
mob= obj.MobileNu;
x= obj.Latitude;
y= obj.Longitude;
time= obj.Time;
}
var j = polySides-1 ;
oddNodes = 0;
for (i=0; i<polySides; i++) {
if (polyLng[i]<y && polyLng[j]>=y || polyLng[j]<y && polyLng[i]>=y) {
if (polyLat[i]+(y-polyLng[i])/(polyLng[j]-polyLng[i])*(polyLat[j]-polyLat[i])<x) {
oddNodes=!oddNodes;
}
}
j=i; }
if(oddNodes!=true)
{
// alert("ob mobile:"+mob);
$.post('obsouth.jsp',
{
pcd:pcode,
npt:nplate,
drv:driver,
mobl:mob,
lat:x,
lon:y,
tm:time
},
function(response,status,xhr)
{
alert(response.trim());
});
}
return oddNodes;
}
});
</script>
My question:-
Is there any technique to call a javascript function from a java class extended with runnables or directly implement the exact javascript in java class?
If answer for 1 is no, can you please guide me to convert my entire javascript to Java code?
Any piece of code is highly appreciated and thanks in advance.
Use node.js and execute your script using Runtime.exec(). you would run node on this or you can go for Rhino scripting engine to envoke methods in .js file from within a java class. Hope that helped.