Using Encapsulation to Make an Awesome Angular JS Editor in Fiddle Salad
Angular JS is a popular MVC framework by Google, and I received a bug report that Fiddle Salad wouldn’t reload the preview as it does in all other cases. This problem was noticed before, but it wasn’t a priority since pressing the refresh button as required in all other web development methods solves the problem. However, this was because I was attempting to solve it at the wrong level by modifying a method. As I’ve learned, there are dependencies between the execute, reset, and initiation of the class involved.
Fiddle Salad’s CodeRunner class has just 5 public methods. They are
- execute()
- add_file()
- remove_css()
- reset()
- debug()
as in the class diagram on the wiki at https://github.com/yuguang/fiddlesalad/wiki/2.-Classes. Therefore, any implementation of a CodeRunner just needs to support these 5 methods. The debug method could be refactored into a super class because it would generate the template for the new execute() method.
###
Debug opens a new window with the code loaded in the page. External CSS and JS files are loaded through head tags.
It assumes all external resources are stored in the view model.
###
template =
css: _.template '<link rel="stylesheet" type="text/css" href="<%= source %>" />'
js: _.template '<script type="text/javascript" src="<%= source %>"></script>'
html: _.template """
<!DOCTYPE html>
<html>
<head>
<title>Fiddle Salad Debug View</title>
<script src="http://leaverou.github.com/prefixfree/prefixfree.min.js"></script>
<style>
<%= css %>
</style>
</head>
<body>
<%= body %>
<%= headtags %>
<script type="text/javascript">
<%= javascript %>
</script>
</body>
</html>
"""
# initialize array of head tags
headTags = new Array
# for each external resource in view model
_.each viewModel.resources(), (resource) =>
# get the file type of the resource, call mapped template with resource, and append generated HTML to head tags
headTags.push template[@filetype resource.source()](source: resource.source())
headtags = headTags.join('')
# get JavaScript and CSS code from the engine
javascript = engine.get_code LANGUAGE_TYPE.COMPILED_PROGRAM
body = engine.get_code LANGUAGE_TYPE.COMPILED_DOCUMENT
css = engine.get_code LANGUAGE_TYPE.COMPILED_STYLE
# call the template for the window with the head tags and code
html = template.html {javascript, css, body, headtags}
# open window with generated HTML
window.open = 'data:text/html;charset=utf-8,' + encodeURIComponent(html)
If I just change the last line, the debug method turns into a reset method.
The rest of the class still needs to be completed, but they are as obvious as appending to an array when adding JS/CSS files.