Call Back Editable IFrames Changes into Codemirror - javascript

http://jsbin.com/aNirEnUB/3/edit
I've been experimenting with Codemirror for a bit, and today I decided to make the iframe editable, but haven't figured out a way to call back the changes I make to the iframe via change and apply those changes directly to Codemirror.
Is this possible?
JavaScript/JQuery:
var delay;
// Initialize CodeMirror editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: 'text/html',
tabMode: 'indent',
styleActiveLine: true,
lineNumbers: true,
lineWrapping: true,
autoCloseTags: true
});
// Live preview
editor.on("change", function() {
clearTimeout(delay);
delay = setTimeout(updatePreview, 300);
});
function updatePreview() {
var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open();
preview.write(editor.getValue());
preview.close();
}
setTimeout(updatePreview, 300);
// Make the preview editable
window.onload = function() {
preview.document.designMode = 'On';
};
// Update the Editor Code from Preview Edit
preview.on('change', function() {
clearTimeout(delay);
delay = setTimeout(updateEditor, 300);
});
function updateEditor() {
var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open();
editor.setValue(preview.body.innerHTML());
preview.close();
}
setTimeout(updateEditor, 300);
HTML:
<textarea id="code" name="code"><!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>HTML5 canvas demo</title>
<style>p {font-family: monospace;}</style>
</head>
<body>
<p>Canvas pane goes here:</p>
<canvas id=pane width=300 height=200></canvas>
<script>
var canvas = document.getElementById('pane');
var context = canvas.getContext('2d');
context.fillStyle = 'rgb(250,0,0)';
context.fillRect(10, 10, 55, 50);
context.fillStyle = 'rgba(0, 0, 250, 0.5)';
context.fillRect(30, 30, 55, 50);
</script>
</body>
</html></textarea>
<iframe id="preview"></iframe>

Via
https://developer.mozilla.org/en-US/docs/Web/API/Window.frames
I've next to no experience with codemirror, but raw DOM allows access to iframes using Window.frames[]. If you pull the data back in through dom using .addEventListener("onchange",function), you should be able to work with it.
If this answer isn't specific enough (or out of scope, since I don't know a way to do this inside of your framework), please provide me with what exactly you're trying to pull back, and i'll do some more research.

http://jsbin.com/aNirEnUB/4/edit
This is the best I've been able to do.
I got rid of Codemirror, and used a regular textbox/textarea.
I set it all up in a form for easier callbacks.
I could not figure out how to callback an onchange or onkeyup event for the iframe. So instead I call it back by toggling the textbox.
window.onload = function() {
preview.document.designMode = 'On';
preview.document.execCommand("enableObjectResizing", false, "false");
preview.document.execCommand("enableInlineTableEditing", false, "false");
};
// Calls code from preview to textbox
function submit_form() {
var theForm = document.getElementById("container");
theForm.elements.code.value = window.frames.preview.document.body.innerHTML;
theForm.onclick();
}
$(document).ready(function() {
var code = $('#code'),
preview = $('[ID$=preview]');
// Live Debugging
code.keyup(IntPrev);
function IntPrev(e) {
preview.contents().find('body').html(code.val());
}
// Toggle between Designer and Code
$("#design-n-code").click(function() {
preview.toggle();
code.toggle();
}); code.hide();
});

Related

how to save a picture taken with window.getusermedia in js

Currently i am working on a open webapp camera, right now i have implemented the camera setup(live stream as viewport, take picture button, capture, display taken picture in corner... etc) but now i am running into the issue of how to save that picture for the user to their device or computer, this app is currently being designed for mobile b2g primarily. I know most people are gonna tell me security issues!!! i dont mean tell the device exactly where to put it. I mean something like
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script type="text/javascript">
window.onload = function () {
var img = document.getElementById('embedImage');
var button = document.getElementById('saveImage');
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA'+
'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO'+
'9TXL0Y4OHwAAAABJRU5ErkJggg==';
img.onload = function () {
button.removeAttribute('disabled');
};
button.onclick = function () {
window.location.href = img.src.replace('image/png', 'image/octet-stream');
};
};
</script>
</head>
<body>
<img id="embedImage" alt="Red dot"/>
<input id="saveImage" type="button" value="save image" disabled="disabled"/>
</body>
</html>
that specific code executed on mobile triggers the file to automatically be saved on click of the button. now what i want to do is use that to take my picture from its var its in and save it as that file, for example that will be in downloads folder.
this is what my code is currently https://github.com/1Jamie/1Jamie.github.io
any help would be appreciated and this is the current running implementation if you want to take a working look http://1Jamie.github.io
This worked for me when I was playing around with getUserMedia - I did notice that you did not have the name of the method in the proper case and it is a method of the navigator.mediaDevices interface - not a method of the window directly...
References:
[Navigator for mozilla]https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS/API/Navigator
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices
[mediaDevices for chrome and android]https://developers.google.com/web/updates/2015/10/media-devices?hl=en
var video = document.getElementById('monitor');
var canvas1 = document.getElementById('photo1');
var img1 = document.getElementById('canvasImg');
navigator.mediaDevices.getUserMedia({
video: true
}).then(function (stream) {
video.srcObject = stream;
video.onloadedmetadata = function () {
canvas1.width = video.videoWidth;
canvas1.height = video.videoHeight;
document.getElementById('splash').hidden = true;
document.getElementById('app').hidden = false;
};
}).catch(function (reason) {
document.getElementById('errorMessage').textContent = 'No camera available.';
});
function snapshot1() {
canvas1.getContext('2d').drawImage(video, 0, 0);
}
"save_snap" is the id of a button - Disclaimer I am using jQuery- but you should easily see where this corresponds to your code:
$("#save_snap").click(function (event){
// save canvas image as data url (png format by default)
var dataURL = canvas2.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
$('#canvasImg').attr("src" , dataURL);
$('#downloader').attr("download" , "download.png");
$('#downloader').attr("href" , dataURL);
//* trying to force download - jQuery trigger does not apply
//Use CustomEvent Vanilla js: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
// In particular
var event1 = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
//NOW we are effectively clicking the element with the href attribute:
//Could use jQuery selector but then we would have to unwrap it
// to expose it to the native js function...
document.getElementById('downloader').dispatchEvent(event1);
});

Performance jQuery Ajax load game sources display as modal

I have a base website system which is using ajax load content without refreshing pages. I have a game page that load many html5 game links via ajax json and when I click on any games it will load the game source files which display as pop up. I am wonder while I'm playing then if I click the close button for stopping the game and then I remove the element of the source files game. Will it free up the memory? As I have noticed, it seems to getting slow the broswer. Anyone has experienced with that, please share with me.
Note: I need some suggestions in order to remove the elements and free up the memory.
eg:
<div id="pop-up">
<a id="close" href="#">Close Button</a>
<div id="inner-pop-up">
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<div id="game">
<canvas></canvas>
</div>
</div>
</div>
$('#pop-up').modal('view', {
speed: 750,
close: '.close-favourite',
easing: 'easeOutBounce',
animation: 'top',
position: 'center',
overlayClose: true
});
$('#close').on('click', function() {
$('#inner-pop-up').children().remove();
});
The only real way to free up any resources used by script functions is to add a JavaScript file that basically calls delete window.myFunction for every possible object and function (functions are objects really) your specified script files may define. To me, for obvious reasons, this is a really bad idea.
Note that these objects would be script (window) objects so you cannot use .remove() to remove those.
I would also note that your should use $('#inner-pop-up').empty(); rather than your $('#inner-pop-up').children().remove(); since that would remove the text of the element if any, as well and specifically removes the data and event handlers from those elements prior to removal from the DOM.
You might have some very specific functions and objects from your scripts that you might want to remove here but only the contents of your scripts would tell that. If you create global window objects that gets really messy fast.
Note it is REALLY hard to determine what a script file creates and then remove it.
To prove a point open up your favorite browser console and execute $("script").remove(). stuff in that script still runs.
Eg: This is my game file which contained the object like that
FootballChallenge.Game = function (game) {
FootballChallenge._scoreText = null;
FootballChallenge._score = 0;
FootballChallenge.kickBoard;
this._preventClick = true;
FootballChallenge.kaboomGroup;
FootballChallenge.ball;
FootballChallenge.shoe;
FootballChallenge.self;
};
FootballChallenge.Game.prototype = {
create: function () {
FootballChallenge.self = this.game;
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.game.physics.arcade.checkCollision.up = false;
this.bg = this.game.add.image(this.game.world.centerX, this.game.world.centerY, 'field');
this.bg.anchor.setTo(0.5);
FootballChallenge.kickBoard = this.game.add.sprite(10, 20, 'kickBoard');
FootballChallenge._scoreText = this.game.add.bitmapText(0, FootballChallenge.kickBoard.height/2 + 20, 'white-font', ''+FootballChallenge._score+'', 32);
FootballChallenge._scoreText.align = 'center';
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
FootballChallenge.ball = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY - 100, 'ball');
this.game.physics.arcade.enable(FootballChallenge.ball);
FootballChallenge.ball.anchor.setTo(0.5);
FootballChallenge.ball.scale.setTo(0.5);
FootballChallenge.ball.body.collideWorldBounds = true;
FootballChallenge.ball.body.gravity.y = 0;
FootballChallenge.ball.body.bounce.setTo(1);
FootballChallenge.shoe = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, 'shoe');
this.game.physics.arcade.enable(FootballChallenge.shoe);
FootballChallenge.shoe.anchor.setTo(0.5);
FootballChallenge.shoe.scale.setTo(0.5);
FootballChallenge.shoe.body.setSize(130,50,0,20);
FootballChallenge.shoe.body.collideWorldBounds = true;
FootballChallenge.kaboomGroup = this.game.add.group();
FootballChallenge.kaboomGroup.createMultiple(10, 'kaboom');
FootballChallenge.kaboomGroup.forEach(this.explosion, this);
this.play();
},
explosion: function(kick) {
kick.anchor.x = 0.7;
kick.anchor.y = 0.5;
kick.animations.add('kaboom');
},
play: function() {
this.bitmask = this.game.make.bitmapData(this.game.width, this.game.height);
this.bitmask.fill(50,50,50);
this.mask = this.game.add.sprite(0, 0, this.bitmask);
this.mask.tint = 0x000000;
this.mask.alpha = 0.6;
this.game.paused = true;
var pausedText = this.game.add.bitmapText(this.game.world.centerX, this.game.world.centerY - 200, 'white-font', 'click anywhere to begin!', 32);
pausedText.align = 'center';
pausedText.tint = 0xff0e25;
pausedText.anchor.setTo(0.5);
this.game.input.onDown.add(function(){
pausedText.destroy();
this.game.paused = false;
this.mask.alpha = 0;
FootballChallenge.ball.body.gravity.y = 1500;
this.game.canvas.style.cursor = "none";
}, this);
},
countScore: function(ball, shoe) {
ball.body.velocity.y = -1000;
ball.body.gravity.x = FootballChallenge.self.rnd.integerInRange(-80, 80);
FootballChallenge._scoreText.setText(FootballChallenge._score +=1);
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
var boom = FootballChallenge.kaboomGroup.getFirstExists(false);
boom.reset(shoe.x, shoe.y);
boom.play('kaboom', 40, false, true);
},
lose: function() {
this.game.state.start('EndGame');
},
update: function() {
if(FootballChallenge.ball.y >= this.game.height - 100) {
FootballChallenge.ball.body.gravity = false;
this.game.time.events.add(Phaser.Timer.SECOND * 0.2, this.lose, this);
}
this.game.physics.arcade.collide(FootballChallenge.ball, FootballChallenge.shoe, this.countScore);
this.game.physics.arcade.moveToPointer(FootballChallenge.shoe, 30, this.game.input.activePointer, 50);
}
};

CodeMirror with 2 text editors and live preview?

I'm trying to create a live editor like jsfiddle where users can put html in html box (textarea) and css in css box(textarea) and preview the changes live in an iframe.
I am using codemirror as the editor.
So far I can only get the preview of one of the textareas in my iframe and I cannot figure out how to get the values of both textareas (css/html) and display them in my iframe exactly like jsfiddle.
This is what I have so far:
http://jsfiddle.net/vwqgtznv/
and this is my javascript code:
<script>
var delay;
// Initialize CodeMirror editor with a nice html5 canvas demo.
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
lineNumbers: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'text/html'
});
editor.on("change", function() {
clearTimeout(delay);
//alert("hellooooo");
delay = setTimeout(updatePreview, 300);
});
function updatePreview() {
var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open();
preview.write(editor.getValue());
preview.close();
}
setTimeout(updatePreview, 300);
</script>
<script>
var delay2;
// Initialize CodeMirror editor with a nice html5 canvas demo.
var editor2 = CodeMirror.fromTextArea(document.getElementById('codert'), {
lineNumbers: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'text/html'
});
editor2.on("change", function() {
clearTimeout(delay2);
//alert("hellooooo");
delay2 = setTimeout(updatePreview2, 300);
});
function updatePreview2() {
var previewFrame2 = document.getElementById('preview');
var preview2 = previewFrame2.contentDocument || previewFrame2.contentWindow.document;
preview2.open();
preview2.write(editor2.getValue());
preview2.close();
}
setTimeout(updatePreview2, 300);
</script>
could someone please help me out and advise on this issue?
Thanks in advance.
Your problem is append CSS to iframe head. Use the code below to update your iframe head for CSS.
function loadCSS() {
var $head = $("#preview").contents().find("head");
$head.html("<style>" + editor.getValue() + "</style>");
};
HTML textarea should be updated with CSS. Add loadCSS() to your updatePreview2()(html textarea update function).
function updatePreview2() {
var previewFrame2 = document.getElementById('preview');
var preview2 = previewFrame2.contentDocument || previewFrame2.contentWindow.document;
preview2.open();
preview2.write(editor2.getValue());
preview2.close();
// added this line
loadCSS();
}
And when your CSS textarea changes, the preview content will be updated by updatePreview()(CSS textarea update function) with CSS content. It should update head only.
function updatePreview() {
loadCSS();
}
Here is the Jsfiddle, please take a demo here.
By the way, try to name your variable and function precisely will make more people help you.
Update
A clean JsFiddle version.
Building upon #North's answer and guidance, I propose this answer. If you +1 this answer, please give +1 to North's answer as well. This is an optimization and expansion up North's anwser, building up a jsfiddle-clone. It therefor demo an answer to the question of this current page.
Jsfiddle -- richer code to go further
Blogpost -- Medium post with some other helpers.
In .html :
<!-- load the relevant dependencies via script and style/link tags. -->
<textarea class="code" id="editor-html">
<textarea class="code" id="editor-css">
<textarea class="code" id="editor-js">
In .js file :
var editorsSettings = {
lineWrapping: true,
lint: true,
lineNumbers: true,
foldGutter: true,
gutters: ["CodeMirror-lint-markers","CodeMirror-linenumbers", "CodeMirror-foldgutter"],
tabSize: 2,
indentUnit: 2,
matchBrackets: true
}
// Editors HTML, CSS, JS : init, bind, define settings.
let editorHTML = CodeMirror.fromTextArea(document.querySelector('#editor-html'), {
mode : "htmlmixed", // require modes for xml, css, js.
htmlMode: true,
...editorsSettings
});
let editorCSS = CodeMirror.fromTextArea(document.querySelector('#editor-css'), {
mode: 'text/css',
...editorsSettings
});
let editorJS = CodeMirror.fromTextArea(document.querySelector('#editor-js'), {
mode: 'text/javascript',
...editorsSettings
});
// Fetch and organize into results
let updatePreview = function() {
let preview = document.querySelector('#preview');
let previewDocument = preview.contentDocument || preview.contentWindow.document;
previewDocument.open();
previewDocument.write(editorHTML.getValue());
previewDocument.write("<script>"+editorJS.getValue()+"<"+"/script>");
previewDocument.close();
previewDocument.querySelector('head').innerHTML = '<style>' + editorCSS.getValue() + '</style>';
}

Image not loading from startup

I have this code im using on my website but the image does not load when page opens, I want the image to load from start up then a simple mouse over to change image and a link when clicked. Im not good at coding so any help would be good.
here is the code im using.
<!doctype html>
<html>
<body>
<head>
<script>
function init() {
setImageOne();
}
function setImageOne() { setImage('http://earthbounds.com/banners/amazing food.jpg'); }
function setImageTwo() { setImage('http://earthbounds.com/banners/amazing food 2.jpg'); }
function setImage(src) {
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
if (context == null) return;
var img = new Image();
img.src = src;
context.drawImage(img, 0, 0, 322, 200);
}
</script>
</head>
No Canvas Support in Browser
You need to wait for the image to load before you draw it. Also, if your browser doesn't support canvas nothing will help you with this approach.
function setImage(src) {
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
if (context == null) return;
var img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0, 322, 200);
};
img.src = src;
}
You should wait for the image to load. Thus your code should be (with corrections regarding html markup):
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="e" style="width: 100%; height: 100%;"></canvas>
<script>
function init() {
setImageOne();
}
function setImageOne() { setImage('http://earthbounds.com/banners/amazing food.jpg'); }
function setImageTwo() { setImage('http://earthbounds.com/banners/amazing food 2.jpg'); }
function setImage(src) {
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
if (context == null) return;
var img = new Image;
img.onload = function (){
context.drawImage(img, 10, 10);
};
img.src = src;
}
init();
</script>
</body>
</html>
This only works in browsers that support canvas ex: Chrome(ium)
Also I suggest you read this
Is this the first method you tried? If you are just trying to add an image on a website and a hover over it there is a much simpler way.
First off, instead of using Javascript to create and load an Image, use the HTML <img> tag, example:
<img src="http://earthbounds.com/banners/amazing food.jpg">
Now to add a simple hover image change, this is not the best practice but for an example, and for a single image you can use onmouseover and onmouseout, example:
<img src="http://earthbounds.com/banners/amazing food.jpg" onmouseover="this.src('http://earthbounds.com/banners/amazing food 2.jpg')" onmouseout="this.src('http://earthbounds.com/banners/amazing food.jpg')">
Now to make this image a link to another page, or website you use the <a> tag, example:
<img src="http://earthbounds.com/banners/amazing food.jpg" onmouseover="this.src('http://earthbounds.com/banners/amazing food 2.jpg')" onmouseout="this.src('http://earthbounds.com/banners/amazing food.jpg')">
Hope this helps, and keep looking and learning!

jQuery and javascript code on same page doesn't work

I have a problem about jQuery and javascript code; when I write this jQuery below between </head> and <body>
<script type="text/javascript">
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j('#page_effect').fadeIn(3000);
});
</script>
and then write javascript code in body tag
<script src="bubbles.js"></script>
<script type="text/javascript">
bubblesMain(new Object({
type : 'linear',
minSpeed : 100,
maxSpeed : 400,
minSize : 30,
maxSize : 55,
num : 100,
colors : new Array('#FF0000','#FFFFFF','#FFCC99', '#FF33CC')
}));
</script>
then jQuery code can work , but javascript code doesn't work. Finally I found that when I resize the browser after the first loading, it's OK to run.
the bubble.js is to automatically create a canvas element and then raises some bubbles with animation inside canvas.
the partly code is on below :
function bubblesMain(obj){
bubbleResize();
bubbles = new bubbleObject(obj);
bubbles.createBubbles();
setInterval(start,1000/60);
};
//WHEN WINDOW HEIGHT IS CHANGED, REMAKE THE CANVAS ELEMENT
window.onresize = function(event) {
bubbleResize();
}
function bubbleResize(){
var height = parseInt(document.getElementById("canvasBubbles").clientHeight);
var width = parseInt(document.getElementById("canvasBubbles").clientWidth);
document.getElementById("canvasBubbles").innerHTML = '<canvas id="canvas" width="'+width+'px" height="'+height+'px"></canvas>';
}
function start(){
var canvas = document.getElementById("canvas");
canvas.width = canvas.width;
bubbles.move();
bubbles.draw();
};
and I have a <div id="canvasBubbles"></div> indise html.
Then after I added the following code into bubbles.js, It's work to run.
window.onload = function(event) {
bubbleResize();
}
I wonder if someone can suggest a smarter solution to this? thank you.
As stated in the other answers, the <script> tags should be the last thing before the </body> tag. See this question.
The problem with where you've put the tags is that the body of the HTML page hasn't loaded and is therefore not available for manipulation. The reason the window.onload and window.onresize work is because they are called later, when the body of the document is available for manipulation with JS.
Given the details provided in your question, you don't need the jQuery.noConflict() statement.
Here is an alternate version of your code that should do the same thing but with a bit more efficiency. Put it at the end of the body element, just before the </body> tag. I haven't tested it since I don't have all the scripts needed (bubbles, etc).
<!-- this goes at the end of your body element, just before the closing tag -->
<script type="text/javascript" src="bubbles.js"></script>
<script type="text/javascript">
$.ready(function(){
var canvasWrap,
canvasElm,
bubbles;
init();
setInterval(update, 1000/60);
window.onresize = resize;
$('#page_effect').fadeIn(3000);
function init(){
canvasWrap = document.getElementById("canvasBubbles");
canvasElm = document.createElement('canvas');
canvasElm.setAttribute('id', 'canvas');
canvasElm.setAttribute('width', canvasWrap.clientWidth);
canvasElm.setAttribute('height', canvasWrap.clientHeight);
canvasWrap.appendChild(canvasElm);
bubbles = new bubbleObject({
type: 'linear',
minSpeed: 100,
maxSpeed: 400,
minSize: 30,
maxSize: 55,
num: 100,
colors: ['#FF0000','#FFFFFF','#FFCC99', '#FF33CC']
});
bubbles.createBubbles();
update(); // you might not need this
}
function resize() {
canvasElm.setAttribute('width', canvasWrap.clientWidth);
canvasElm.setAttribute('height', canvasWrap.clientHeight);
}
function update(){
// canvasElm.width = canvasElm.width; // is this a hack for something?
bubbles.move();
bubbles.draw();
};
});
</script>
You can write all this inside <body>...</body> or inside <head> ... </head>
NOT works between </body> and <head> tag (maybe works for some less formal browser like old IE).
Script tags should always go at the bottom of the page directly before the tag unless the codes needs to be executed before then for some reason.
And as far as I know, the jQuery noConflict() method is only required when you are using two different libraries that both use the dollar sign, aka jQuery and MooTools, on the same page. You can use jQuery and vanilla javascript without having to use noConflict without any problems.

Categories

Resources