window.alert() is not available in packaged apps - javascript

I am making a Chrome application. I keep getting the error in console:
window.alert() is not available in packaged apps. extensions::platformApp:17
Line 17 of that file is just a line of code to log the error to the console. Is there a way to alert the user of an event in a chrome app (like this image?)Is it because I have adblock installed in Firefox (I don't use Chrome)? I thought alert() was pretty basic. Thanks for any help.

The alert function has been disabled in Chrome packaged apps, because it halts the execution of Javascript and thus provides a poor user experience. For development purposes you should use console.log and for user facing interactions you should use a HTML based dialog.

You can make your own synchronous alert/prompt with a function that waits for a jQuery promise before completion and then when the user clicks the "OK" button resolves the promise. Then when ever you replace your "alert" with "myCustomAlert" you have to declare the function it's called in as an "async function" and then "await" before the call.
This may sound complicated but if you play with it in JSFiddle it's quite simple.
I found this useful if you are porting over an app where you can't break the function up into different sections very easily. This does requires the jQuery library.
Here is my example https://jsfiddle.net/littlej247/g4k2h56c/5/
//*****HTML*********
<button type="button" id="alertMe">Alert ME!</button>
<div id="backgroudDiv"> <!-- This is optional but I like to grey out the background -->
<div id="alertDiv">
<b><span id="alertTitle"></span></b>
<br />
<span id="alertText"></span>
<hr>
<button type="button" id="alertDone">OK</button>
</div>
</div>
//Remember JS can't run in HTML files on chrome apps so functions are called by DOM
document.getElementById("alertMe").onclick = async function () {
console.log("Starting function \n Processing a bunch of stuff, calculating variable(s)....");
await myCustomAlert("Alert Title Here","Message");
console.log("Continue processing stuff with the variable(s) after the alert is clicked.... \n function finished");
};
//*****JavaScript*********
//Alerts can not be used in chrome apps, myCustomAlert function is a replacement.
var alertPromise
function myCustomAlert(messageTitle,messageBody){
console.log("myCustomAlert has been called");
alertPromise = $.Deferred();
document.getElementById("alertTitle").textContent=messageTitle;
document.getElementById("alertText").textContent=messageBody;
document.getElementById('backgroudDiv').style.display='block';
return $.when(alertPromise).done();
}
document.getElementById("alertDone").onclick = function () {
console.log("Finally, User clicked Done, \n now we can get back to work..");
document.getElementById('backgroudDiv').style.display='none';
alertPromise.resolve();
return(false);
};
//*****Styles*********
#alertDiv {
width: 400px;
padding: 15px;
margin: 100px auto auto auto;
z-index: 10000;
background-color: lightblue;
border-style: solid;
border-color: black;
}
#backgroudDiv {
display: none;
position: fixed;
z-index: 9000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
}

Related

Div class change not showing during .each loop

I have a javascript function triggered by a button click. I add a class to an element before going into an 'each' loop.
When running the code in the page, I do not see the change. But if I pause the code in the debugger, I do.
The code is set up like this:
$("#btnApplyDefaults").on('click',
function (e) {
$('#loader').addClass("loading-page");
$('#pricingSheetItems tr').filter(':has(:checkbox:checked)').each(function() {
// Do some stuff
});
$('#loader').removeClass("loading-page");
});
If I run this with data that takes a long time to run, I never see the loading image. But if I have a breakpoint, and walk through I see the image.
Here's the class:
div.loading-page {
position: absolute;
left: 50%;
background-image: url("../../dist/img/loading.gif");
background-repeat: no-repeat;
content: "";
display: block;
width: 32px;
height: 32px;
}
I'm assigning it to this div:
<div tabindex="-1" class="" id="loader"></div>
All of your code runs synchronously, meaning that it completes all of it before your UI responds. You add the loading class at the beginning, do some operations, and remove the class, all before the UI can respond.
If you want your UI to update, you can add a minor pause via setTimeout:
$("#btnApplyDefaults").on('click',
function (e) {
$('#loader').addClass("loading-page");
setTimeout(function () {
$('#pricingSheetItems tr').filter(':has(:checkbox:checked)').each(function() {
// Do some stuff
});
$('#loader').removeClass("loading-page");
}, 0);
});
This should show the loading class. I suspect it won't animate though, because your page will be busy doing computations. You should look into using WebWorkers or some sort of asynchronous worker for a better user experience.

Using browser to find the javascript code currently running

Is it possible to find the javascript code for current event using the console, on any browser?
For example, please see this JSFiddle. This is the corresponding code:
.close-icon {
border:1px solid transparent;
background-color: transparent;
display: inline-block;
vertical-align: middle;
outline: 0;
cursor: pointer;
}
.close-icon:after {
content: "X";
display: block;
width: 15px;
height: 15px;
/*position: absolute;*/
float:right;
background-color: #FA9595;
z-index:1;
right: 35px;
top: 0;
bottom: 0;
margin: auto;
padding: 2px;
border-radius: 50%;
text-align: center;
color: white;
font-weight: normal;
font-size: 12px;
box-shadow: 0 0 2px #E50F0F;
cursor: pointer;
}
<input type="range" min="12" max="120" id="slider" />
<div class="text" contenteditable="true" style="cursor:grab;">hello1<button class="close-icon dbutton" type="reset"/></div>
<div class="text text1" contenteditable="true" style="cursor:grab;">hello2<button class="close-icon dbutton1" type="reset"/></div>
<div class="text text2" contenteditable="true" style="cursor:grab;">hello3<button class="close-icon dbutton2" type="reset"/></div>
<div class="text text3" contenteditable="true" style="cursor:grab;">hello4<button class="close-icon dbutton3" type="reset"/></div>
$("#slider").on("change",function(){
var v=$(this).val();
$('.text.active').css('font-size', v + 'px');
});
$('.text').on('focus',function(){
$('.text').removeClass('active');
$(this).addClass('active');
});
$(document).on("click",".close-icon",function(){
$(this).closest('div').remove();
//alert('hiii');
});
Here I write the code to enlarge the text and close the div. Now is it possible to see the code responsible for resizing the text, when I am resizing the that text?
UPDATE : I know how to inspect element, change style and other things
. But here i am asking to know how to detect the javascript code or
function for the current event.Hi, it's not about console .log
function . I know this already . I am asking that how to know which
function is working when i click the close button , how can i see that
code in browser . Here i write the code , i understand where the code
is . What about if some other write the code and i am looking browser
for detecting what code and what event is running
You can run the console.log() function on the browser console in situations where it could return useful info for debugging. For example, if you add, on your script, console.log() as:
$("#slider").on("change",function(){
var v=$(this).val();
console.log(v);
...
});
Then open it in the browser and activate the inspector (shift + cmd + i on Chrome on the Mac, for example), and click on the Console tab: you should see the value of v changing.
Checking which code is responsible for specific tasks may be tricky. One way you can try is to, using Chrome, open the Console, click on the Sources tab, and click on the little pause icon (pause script execution). Then, when any javascript tries to run, Chrome will pause and show you the code. The problem with this approach is that many times there is a loop running constantly. And if that's the case, as soon as you press pause, Chrome will show you the line of javascript of that loop, and you won't have time to actually execute the action you're interested at finding the code for.
If you have an idea of which script is running, you can click the Sources tab, browse to the javascript file that has the code, and add a breakpoint. Then you can execute the action, and if the action involves that piece of code, Chrome will pause at that breakpoint. In the same tab (Sources), try to click the line number, and set "Never pause here". Even though this method won't help you out with every possible code you may be inspecting, sometimes it will.
Also on Chrome, use the console search (open console then cmd + alt + f on Chrome for Mac) to search through all the resources loaded on that page. If you know you're looking for a script that deals with a certain CSS class or id, you can search for this id or class, see if you can find it on a javascript resource, and add a breakpoint. When you get to that point, the script will pause, and you will be able to run commands on the console. If your break point was, say, in a class method, then you would be in the scope of that class method context.
You can use Inspect Element on Chrome by right click to see your code. Select source tab from the inspect window. Same way in Firefox too. Place a break in corresponding event. Using Firebug in Firefox will be better.
Update: examples attached.
To open DevTools hit Ctrl + Shift + I on windows then tab Console use examples below:
console.log("test");//add this were ever you want to test
//examples
Element.onclick = function(){
console.log("clicked");
}
Element.onkeyup = function(){
console.log("keyup detection");
}
window.onload = function(){
console.log("page loaded");
}
Also to catch error by line you can use
try{
var invalid = "hello world';//<===== here is invalid string
}catch(e){
console.log(e.stack);//catched error details (line, file, error)
}
is it possible see the code for resize the text when i am resizing the that text ?
Example to detect button click, focus and range change
Check Fiddle

keep window hidden until init completes

I am creating an window with a significant initialization process and I would like to keep the window hidden until init finishes. Right now at the beginning of my js code I hide the window right after it is created and then show it when init is complete. But this creates a less than pleasing flash when the app is launched as the window appears, disappears and then re-appears.
Is there a way to keep the window invisible while the init runs?
My best guess, without seeing your code, is that you need to hide the application window using CSS in the head section of your page. This way it is hidden before the browser ever renders the page. Trying to hide the window with Javascript won't work as nicely. That's because the script can't hide the window until after the browser creates it. So, depending on conditions, the user might see it flash on start.
The snippet below shows how to do this using the CSS visibility attribute. Alternatively, you may also use the display attribute.
Show and then run the snippet to try.
setTimeout(function() {
// some long init process here
// make visible on ready
window.spinner.style.display = 'none';
window.app.style.visibility = 'visible';
}, 3000);
#app {
height: 10em;
visibility: hidden;
background-color: white;
}
h3,
h4 {
margin: 0;
padding: 4px;
color: white;
background-color: steelblue;
}
#spinner {
height: 100px;
position: absolute;
}
body {
background-color: lightgray;
}
<h3>Header</h3>
<div id="content">
<img id="spinner" src="http://i.stack.imgur.com/kOnzy.gif">
<div id="app">APPLICATION READY</div>
</div>
<h4>footer</h4>
I agree with #jeff about providing some sort of progress indicator. However, the standard way to create a window that's hidden by default in Electron is to use the show option when creating the browser window:
const myWindow = new BrowserWindow({ show: false });
Then when loading/processing is finished you can make the window visible:
// this code runs in the renderer process
import { remote } from 'electron';
remote.getCurrentWindow().show();
Hide it first with CSS. display: none or visibility:hidden.
Then show with javascript by changing display or visibility after init.

DOM not showing before onload

I am having an issue where my DOM is not displaying when my window.onload (or ) fires. In my actual project, the javascript function I call is gathering quite a bit of data, so I am trying to simply display a splash style screen first. Easy...but it is not working as I expect and I feel I am missing something.
I have seen similar questions, but most of them have an 'alert' as part of the testing solution. Anything that breaks the script running allows the DOM to display...so these 'solutions' are not fixing my issue. If I step through the code (IE or Chrome), then all works fine.
Here is a sample that reproduces the issue. At least when I run this in Chrome, nothing displays until the 3rd second...then the alert pops and the Loading div shows. In IE, Loading Div does not show until all 5 seconds pass and function completes.
Thanks in advance for any thoughts!
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#Loading{
position: absolute;
Left: 50px;
Top: 50px;
width: 100%;
height: 100%;
background-color: yellow;
display: block;
}
</style>
<script>
window.onload = Hmm;
function Hmm(){
i = 0;
while (i < 5){
sleep(1000);
i++;
if (i == 3) {
alert("hi");
}
}
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
</script>
</head>
<body>
<div id="Loading">Loading...</div>
</body>
</html>
I highly recommend you read Events and Timing In-Depth, now. I'm going to assume your actual project code that's "gathering quite a bit of data" is not written asynchronously, much like your test code here.
Here are a few nuggets of knowledge from the linked article:
Most browsers use [a] single thread for UI and JavaScript, which is
blocked by synchronous calls. So, JavaScript execution blocks the
rendering.
Events are processed asynchronously with the exception of DOM events.
And lastly, the rendering pipeline is not the same across browsers. Your results will vary.

Make javascript Alert/Confirm dialogs more visible (especially in the Google Chrome browser)

In recent versions of the Google Chrome browser, javascript Alert dialogs, and Confirm dialogs, are not very visible. They don't make a sound when appearing, they're positioned near the top of the screen, and they're white so they blend in too easily with most websites.
This causes users to not realize the Alert is there, and since the Alert freezes the browser until dismissed, users can easily think their browser is frozen.
What are some ways to make the javascript Alert stand out more?
One option is to create your own Alert, using div overlays. However, doing that for Confirm dialogs would be more difficult, since you often want all execution to stop until the user chooses OK or Cancel on the Confirm dialog.
A great option is the following, which allows you to continue using the browser's Alert and Confirm dialogs:
Create these functions (uses Jquery but can be modified to Javascript):
function alrt(msg) {
var tint = $('<div class="PopupBgTint"></div>');
tint.appendTo('body');
alert(msg);
tint.remove();
}
function cnfrm(msg) {
var tint = $('<div class="PopupBgTint"></div>');
tint.appendTo('body');
var rtrn = confirm(msg);
tint.remove();
return rtrn;
}
In your CSS file, define PopupBgTint like so:
.PopupBgTint
{
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: black;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
z-index:99999;
}
Then, instead of calling
alert('Hello World') or confirm('Continue?')
instead call alrt('Hello World') or cnfrm('Continue?')
That's all there is to it. This will create a temporary tinted overlay covering your entire page, with the Alert/Confirm dialog on top of it, making the dialog MUCH more visible.
See example at:
http://jsfiddle.net/wcU3f/1/
(jsfiddle uses frames though, which negates part of the effect, but you get the idea how it'd function on a full webpage.)

Categories