Ver código fonte

Added Package fetching and Additional-Examples

Added a Package class loading-storing protocol
Added Additional-Examples package
Reformatted index.html; added width and height to image tag
JohnnyT 12 anos atrás
pai
commit
76de1b487a

+ 106 - 113
index.html

@@ -1,115 +1,108 @@
-<!DOCTYPE html> 
-<html> 
-  <head> 
-    <title>Amber Smalltalk</title> 
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
-    <meta name="author" content="Nicolas Petton" /> 
-    <link rel="stylesheet" type="text/css" href='css/style.css' /> 
-    <link type="image/x-icon" rel="shortcut icon" href="/favicon.ico"/> 
-    <link href='http://fonts.googleapis.com/css?family=Istok+Web' rel='stylesheet' type='text/css'> 
-			<script type='text/javascript' src='js/amber.js'></script> 
-		</head> 
-		<body> 
-			
-			<a href="http://github.com/NicolasPetton/amber"><img style="position: absolute; top: 0; lef
-			t: 0; border: 0;" src="https://assets.github.com/img/bec6c51521dcc8148146135149fe06a9cc737577?repo=&url=http%3A%2F%2Fs3.amazonaws.com%2Fgithub%2Fribbons%2Fforkme_left_darkblue_121621.png&path=" alt="Fork me on GitHub"></a> 
-			
-			<div id="wrapper"> 
-				
-				<div id="header"> 
-					<div class="main"> 
-						<div class="logo"> 
-							<img src="images/amber.png"/> 
-						</div> 
-						
-						<ul id="tabs"> 
-							<li><a target="_blank" href="http://amber-lang.net/index.html">Overview</a></li> · 
-							<li><a target="_blank" href="http://amber-lang.net/index.html#download">Download</a></li> · 
-							<li><a target="_blank" href="http://amber-lang.net/learn.html">Learn</a></li> ·
-							<li><a target="_blank" href="http://amber-lang.net/documentation.html">Documentation</a></li> ·
-							<li><a target="_blank" target="_blank" href="https://github.com/NicolasPetton/amber">Source</a></li> 
-						</ul> 
-						
-						<div class="clear"></div> 
-						
-					</div> 
-				</div> 
-				
-				<div class="teaser"> 
-					<div class="main"> 
-						<h1>Welcome aboard!</h1> 
-						<div class="column">
-							<h2>What is Amber?</h2>
-							<p>Amber, formerly known as Jtalk, is an implementation of the Smalltalk-80 language. It is designed to make client-side development faster and easier. It allows developers to write client-side heavy web applications in Smalltalk. </p> 
-							<p>Amber includes an integrated development environment with a class browser, workspace, transcript, object inspector and debugger.</p> 
-							<p>Amber is written in itself, including the compiler, and compiles into efficient JavaScript, mapping one-to-one with the JS equivalent.</p> 
-							<h2>Give it a try!</h2>
-							<p><b>Try a <button onClick="smalltalk.Browser._open()"> Class browser</button> right now!</b></p> 
-						</div> 
-						<div class="column">
-							<h2>Getting started</h2>
-							<p>The <a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a> includes a <a href="https://github.com/NicolasPetton/amber/wiki/Getting-started">Getting started</a> tutorial for OSX, Linux and Windows.</p>
-							<p>If you're new to Smalltalk, You can learn it online with <a href="http://amber-lang.net/learn.html">ProfStef</a>.</p>
-							<h2>Join the community</h2>
-							<ul>
-								<li><a href="http://amber-lang.net">Amber's website</a></li>
-								<li><a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a></li>
-								<li><a href="http://groups.google.com/group/amber-lang">Mailing list</a></li>
-								<li>Join us on IRC at #amber-lang on Freenode</li>
-							</ul>
-						</div>
-						<div class="clear"></div> 
-					</div> 
-					
-					
-				</div> 
-				
-				<div id="content"> 
-					<div class="main"> 
-						<div class="box"> 
-							<h2>Client-side usage</h2> 
-							<div class="content"> 
-								<p>Load the full Amber Smalltalk environment with the IDE in your page:</p> 
-								
-								<code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Amber Smalltalk</title>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+    <meta name="author" content="Nicolas Petton" />
+    <link rel="stylesheet" type="text/css" href='css/style.css' />
+    <link type="image/x-icon" rel="shortcut icon" href="/favicon.ico"/>
+    <link href='http://fonts.googleapis.com/css?family=Istok+Web' rel='stylesheet' type='text/css'>
+    <script type='text/javascript' src='js/amber.js'></script>
+  </head>
+  <body>
+    <a href="http://github.com/NicolasPetton/amber"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://assets.github.com/img/bec6c51521dcc8148146135149fe06a9cc737577?repo=&url=http%3A%2F%2Fs3.amazonaws.com%2Fgithub%2Fribbons%2Fforkme_left_darkblue_121621.png&path=" alt="Fork me on GitHub"></a>
+    <div id="wrapper">
+      <div id="header">
+        <div class="main">
+          <div class="logo">
+            <img src="images/amber.png" width="438" height="164"/>
+          </div>
+
+          <ul id="tabs">
+            <li><a target="_blank" href="http://amber-lang.net/index.html">Overview</a></li> ·
+            <li><a target="_blank" href="http://amber-lang.net/index.html#download">Download</a></li> ·
+            <li><a target="_blank" href="http://amber-lang.net/learn.html">Learn</a></li> ·
+            <li><a target="_blank" href="http://amber-lang.net/documentation.html">Documentation</a></li> ·
+            <li><a target="_blank" target="_blank" href="https://github.com/NicolasPetton/amber">Source</a></li>
+          </ul>
+
+          <div class="clear"></div>
+        </div>
+      </div>
+
+      <div class="teaser">
+        <div class="main">
+          <h1>Welcome aboard!</h1>
+          <div class="column">
+            <h2>What is Amber?</h2>
+            <p>Amber, formerly known as Jtalk, is an implementation of the Smalltalk-80 language. It is designed to make client-side development faster and easier. It allows developers to write client-side heavy web applications in Smalltalk. </p>
+            <p>Amber includes an integrated development environment with a class browser, workspace, transcript, object inspector and debugger.</p>
+            <p>Amber is written in itself, including the compiler, and compiles into efficient JavaScript, mapping one-to-one with the JS equivalent.</p>
+            <h2>Give it a try!</h2>
+            <p><b>Try a <button onClick="smalltalk.Browser._open()"> Class browser</button> right now!</b></p>
+          </div>
+          <div class="column">
+            <h2>Getting started</h2>
+            <p>The <a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a> includes a <a href="https://github.com/NicolasPetton/amber/wiki/Getting-started">Getting started</a> tutorial for OSX, Linux and Windows.</p>
+            <p>If you're new to Smalltalk, You can learn it online with <a href="http://amber-lang.net/learn.html">ProfStef</a>.</p>
+            <h2>Join the community</h2>
+            <ul>
+              <li><a href="http://amber-lang.net">Amber's website</a></li>
+              <li><a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a></li>
+              <li><a href="http://groups.google.com/group/amber-lang">Mailing list</a></li>
+              <li>Join us on IRC at #amber-lang on Freenode</li>
+            </ul>
+          </div>
+          <div class="clear"></div>
+        </div>
+      </div>
+
+      <div id="content">
+        <div class="main">
+          <div class="box">
+            <h2>Client-side usage</h2>
+            <div class="content">
+              <p>Load the full Amber Smalltalk environment with the IDE in your page:</p>
+
+              <code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
 &lt;script type="text/javascript"&gt; loadAmber()&lt;/script&gt;</pre></code>
-							</div> 
-							
-							
-							<p>Or the deployment JavaScript file only (without the Smalltalk sources, parser, compiler and IDE):</p>
-							<code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
+            </div>
+
+
+            <p>Or the deployment JavaScript file only (without the Smalltalk sources, parser, compiler and IDE):</p>
+            <code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
 &lt;script type="text/javascript"&gt; loadAmber({deploy: true})&lt;/script&gt;</pre></code>
-						</div> 
-						
-						<div class="box last examples"> 
-							<h2>Examples</h2> 
-							<div class="content"> 
-								<ul>
-									<li>
-										<a href="examples/trysmalltalk/index.html">
-											<img src="images/profstef.png" alt="Learn Smalltalk with ProfStef"/>
-										</a>
-									</li>
-									<li>
-										<a href="examples/presentation/index.html">
-											<img src="images/presentation.png" alt="ESUG 2011 presentation"/>
-										</a>
-									</li>
-									<li>
-										<a href="examples/twitterwall/index.html">
-											<img src="images/twitterwall.png" alt="Twitter Wall"/>
-										</a>
-									</li>
-									<div class="clear"></div>
-								</ul>
-							</div> 
-						</div> 
-						
-					</div> 
-				</div> 
-			</div> 
-			
-			<script type='text/javascript'> loadAmber() </script> 
-			
-		</body> 
-	</html> 
+          </div>
+
+          <div class="box last examples">
+            <h2>Examples</h2>
+            <div class="content">
+              <ul>
+                <li>
+                  <a href="examples/trysmalltalk/index.html">
+                    <img src="images/profstef.png" alt="Learn Smalltalk with ProfStef"/>
+                  </a>
+                </li>
+                <li>
+                  <a href="examples/presentation/index.html">
+                    <img src="images/presentation.png" alt="ESUG 2011 presentation"/>
+                  </a>
+                </li>
+                <li>
+                  <a href="examples/twitterwall/index.html">
+                    <img src="images/twitterwall.png" alt="Twitter Wall"/>
+                  </a>
+                </li>
+                <div class="clear"></div>
+              </ul>
+            </div>
+          </div>
+
+        </div>
+      </div>
+    </div>
+
+    <script type='text/javascript'> loadAmber() </script>
+
+  </body>
+</html>

+ 15 - 0
js/Additional-Examples.deploy.js

@@ -0,0 +1,15 @@
+smalltalk.addPackage('Additional-Examples', {});
+smalltalk.addClass('ClassInitializationExample', smalltalk.Object, [], 'Additional-Examples');
+
+smalltalk.addMethod(
+'_initialize',
+smalltalk.method({
+selector: 'initialize',
+fn: function (){
+var self=this;
+smalltalk.send((typeof window == 'undefined' ? nil : window), "_alert_", [smalltalk.send(smalltalk.send("Hello from inside the ", "__comma", [smalltalk.send(self, "_printString", [])]), "__comma", [" initialize method."])]);
+return self;}
+}),
+smalltalk.ClassInitializationExample.klass);
+
+

+ 21 - 0
js/Additional-Examples.js

@@ -0,0 +1,21 @@
+smalltalk.addPackage('Additional-Examples', {});
+smalltalk.addClass('ClassInitializationExample', smalltalk.Object, [], 'Additional-Examples');
+smalltalk.ClassInitializationExample.comment=unescape('This%20class%20will%20pop%20up%20an%20alert%20when%20it%20is%20loaded%20into%20Amber.')
+
+smalltalk.addMethod(
+unescape('_initialize'),
+smalltalk.method({
+selector: unescape('initialize'),
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send((typeof window == 'undefined' ? nil : window), "_alert_", [smalltalk.send(smalltalk.send("Hello from inside the ", "__comma", [smalltalk.send(self, "_printString", [])]), "__comma", [" initialize method."])]);
+return self;},
+args: [],
+source: unescape('initialize%0A%09window%20alert%3A%20%27Hello%20from%20inside%20the%20%27%2C%20self%20printString%20%2C%20%27%20initialize%20method.%27'),
+messageSends: ["alert:", unescape("%2C"), "printString"],
+referencedClasses: []
+}),
+smalltalk.ClassInitializationExample.klass);
+
+

+ 48 - 0
js/Kernel-Objects.deploy.js

@@ -1122,6 +1122,54 @@ return self;}
 }),
 smalltalk.Package.klass);
 
+smalltalk.addMethod(
+'_fetch_prefix_',
+smalltalk.method({
+selector: 'fetch:prefix:',
+fn: function (aPackageName, aPrefix){
+var self=this;
+smalltalk.send((typeof jQuery == 'undefined' ? nil : jQuery), "_getScript_onSuccess_", [smalltalk.send(smalltalk.send(aPrefix, "__comma", [aPackageName]), "__comma", [".js"]), (function(){return smalltalk.send((smalltalk.Package || Package), "_init_", [aPackageName]);})]);
+return self;}
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+'_fetch_',
+smalltalk.method({
+selector: 'fetch:',
+fn: function (aPackageName){
+var self=this;
+smalltalk.send(self, "_fetch_prefix_", [aPackageName, smalltalk.send(smalltalk.send(self, "_defaultCommitPathJs", []), "__comma", [unescape("/")])]);
+return self;}
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+'_commitToLocalStorage_',
+smalltalk.method({
+selector: 'commitToLocalStorage:',
+fn: function (aPackageName){
+var self=this;
+var key=nil;
+var sourceCode=nil;
+key=smalltalk.send("smalltalk.packages.", "__comma", [aPackageName]);
+sourceCode=smalltalk.send(smalltalk.send((smalltalk.Exporter || Exporter), "_new", []), "_exportPackage_", [aPackageName]);
+localStorage[key] = escape(sourceCode);
+return self;}
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+'_init_',
+smalltalk.method({
+selector: 'init:',
+fn: function (aPackageName){
+var self=this;
+(function($rec){smalltalk.send($rec, "_do_", [(function(each){return smalltalk.init(each);})]);return smalltalk.send($rec, "_do_", [(function(each){return smalltalk.send(each, "_initialize", []);})]);})(smalltalk.send(smalltalk.send((typeof smalltalk == 'undefined' ? nil : smalltalk), "_classes", []), "_select_", [(function(each){return each.pkg.pkgName == aPackageName;})]));
+return self;}
+}),
+smalltalk.Package.klass);
+
 
 smalltalk.addClass('Number', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.addMethod(

+ 69 - 1
js/Kernel-Objects.js

@@ -1196,7 +1196,7 @@ smalltalk.Smalltalk.klass);
 
 
 smalltalk.addClass('Package', smalltalk.Object, ['commitPathJs', 'commitPathSt'], 'Kernel-Objects');
-smalltalk.Package.comment=unescape('A%20Package%20is%20similar%20to%20a%20%22class%20category%22%20typically%20found%20in%20other%20Smalltalks%20like%20Pharo%20or%20Squeak.%20Amber%20does%20not%20have%20class%20categories%20anymore%2C%20it%20had%20in%20the%20beginning%20but%20now%20each%20class%20in%20the%20system%20knows%20which%20package%20it%20belongs%20to.%0A%0AA%20Package%20has%20a%20name%2C%20an%20Array%20of%20%22requires%22%2C%20a%20comment%20and%20a%20Dictionary%20with%20other%20optional%20key%20value%20attributes.%20A%20Package%20can%20also%20be%20queried%20for%20its%20classes%2C%20but%20it%20will%20then%20resort%20to%20a%20reverse%20scan%20of%20all%20classes%20to%20find%20them.%0APackages%20are%20manipulated%20through%20%22Smalltalk%20current%22%2C%20like%20for%20example%20finding%20one%20based%20on%20a%20name%3A%0A%0A%09Smalltalk%20current%20packageAt%3A%20%27Kernel%27%0A%0A...but%20you%20can%20also%20use%3A%0A%0A%09Package%20named%3A%20%27Kernel%27%0A%0AA%20Package%20differs%20slightly%20from%20a%20Monticello%20package%20which%20can%20span%20multiple%20class%20categories%20using%20a%20naming%20convention%20based%20on%20hyphenation.%20But%20just%20as%20in%20Monticello%20a%20Package%20supports%20%22class%20extensions%22%20so%20a%20Package%0Acan%20define%20behaviors%20in%20foreign%20classes%20using%20a%20naming%20convention%20for%20method%20categories%20where%20the%20category%20starts%20with%20an%20asterisk%20and%20then%20the%20name%20of%20the%20owning%20package%20follows.%20This%20can%20easily%20be%20seen%20in%20for%20example%20class%0AString%20where%20the%20method%20category%20%22*IDE%22%20defines%20%23inspectOn%3A%20which%20thus%20is%20a%20method%20belonging%20to%20the%20IDE%20package.')
+smalltalk.Package.comment=unescape('A%20Package%20is%20similar%20to%20a%20%22class%20category%22%20typically%20found%20in%20other%20Smalltalks%20like%20Pharo%20or%20Squeak.%20Amber%20does%20not%20have%20class%20categories%20anymore%2C%20it%20had%20in%20the%20beginning%20but%20now%20each%20class%20in%20the%20system%20knows%20which%20package%20it%20belongs%20to.%0A%0AA%20Package%20has%20a%20name%2C%20an%20Array%20of%20%22requires%22%2C%20a%20comment%20and%20a%20Dictionary%20with%20other%20optional%20key%20value%20attributes.%20A%20Package%20can%20also%20be%20queried%20for%20its%20classes%2C%20but%20it%20will%20then%20resort%20to%20a%20reverse%20scan%20of%20all%20classes%20to%20find%20them.%0APackages%20are%20manipulated%20through%20%22Smalltalk%20current%22%2C%20like%20for%20example%20finding%20one%20based%20on%20a%20name%3A%0A%0A%09Smalltalk%20current%20packageAt%3A%20%27Kernel%27%0A%0A...but%20you%20can%20also%20use%3A%0A%0A%09Package%20named%3A%20%27Kernel%27%0A%0AA%20Package%20differs%20slightly%20from%20a%20Monticello%20package%20which%20can%20span%20multiple%20class%20categories%20using%20a%20naming%20convention%20based%20on%20hyphenation.%20But%20just%20as%20in%20Monticello%20a%20Package%20supports%20%22class%20extensions%22%20so%20a%20Package%0Acan%20define%20behaviors%20in%20foreign%20classes%20using%20a%20naming%20convention%20for%20method%20categories%20where%20the%20category%20starts%20with%20an%20asterisk%20and%20then%20the%20name%20of%20the%20owning%20package%20follows.%20This%20can%20easily%20be%20seen%20in%20for%20example%20class%0AString%20where%20the%20method%20category%20%22*IDE%22%20defines%20%23inspectOn%3A%20which%20thus%20is%20a%20method%20belonging%20to%20the%20IDE%20package.%0A%0AYou%20can%20fetch%20a%20package%20from%20the%20server%3A%0A%0A%09Package%20fetch%3A%20%27Additional-Examples%27')
 smalltalk.addMethod(
 unescape('_name'),
 smalltalk.method({
@@ -1603,6 +1603,74 @@ referencedClasses: []
 }),
 smalltalk.Package.klass);
 
+smalltalk.addMethod(
+unescape('_fetch_prefix_'),
+smalltalk.method({
+selector: unescape('fetch%3Aprefix%3A'),
+category: 'loading-storing',
+fn: function (aPackageName, aPrefix){
+var self=this;
+smalltalk.send((typeof jQuery == 'undefined' ? nil : jQuery), "_getScript_onSuccess_", [smalltalk.send(smalltalk.send(aPrefix, "__comma", [aPackageName]), "__comma", [".js"]), (function(){return smalltalk.send((smalltalk.Package || Package), "_init_", [aPackageName]);})]);
+return self;},
+args: ["aPackageName", "aPrefix"],
+source: unescape('fetch%3A%20aPackageName%20prefix%3A%20aPrefix%0A%09jQuery%20getScript%3A%20%28aPrefix%20%2C%20aPackageName%20%2C%20%27.js%27%29%20onSuccess%3A%20%5B%20Package%20init%3A%20aPackageName%20%5D'),
+messageSends: ["getScript:onSuccess:", unescape("%2C"), "init:"],
+referencedClasses: ["Package"]
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+unescape('_fetch_'),
+smalltalk.method({
+selector: unescape('fetch%3A'),
+category: 'loading-storing',
+fn: function (aPackageName){
+var self=this;
+smalltalk.send(self, "_fetch_prefix_", [aPackageName, smalltalk.send(smalltalk.send(self, "_defaultCommitPathJs", []), "__comma", [unescape("/")])]);
+return self;},
+args: ["aPackageName"],
+source: unescape('fetch%3A%20aPackageName%0A%09self%20fetch%3A%20aPackageName%20prefix%3A%20self%20defaultCommitPathJs%2C%20%27/%27'),
+messageSends: ["fetch:prefix:", unescape("%2C"), "defaultCommitPathJs"],
+referencedClasses: []
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+unescape('_commitToLocalStorage_'),
+smalltalk.method({
+selector: unescape('commitToLocalStorage%3A'),
+category: 'loading-storing',
+fn: function (aPackageName){
+var self=this;
+var key=nil;
+var sourceCode=nil;
+key=smalltalk.send("smalltalk.packages.", "__comma", [aPackageName]);
+sourceCode=smalltalk.send(smalltalk.send((smalltalk.Exporter || Exporter), "_new", []), "_exportPackage_", [aPackageName]);
+localStorage[key] = escape(sourceCode);
+return self;},
+args: ["aPackageName"],
+source: unescape('commitToLocalStorage%3A%20aPackageName%0A%09%7C%20key%20sourceCode%20%7C%0A%09key%20%3A%3D%20%27smalltalk.packages.%27%20%2C%20aPackageName.%0A%09sourceCode%20%3A%3D%20Exporter%20new%20exportPackage%3A%20aPackageName.%0A%09%3ClocalStorage%5Bkey%5D%20%3D%20escape%28sourceCode%29%3E'),
+messageSends: [unescape("%2C"), "exportPackage:", "new"],
+referencedClasses: ["Exporter"]
+}),
+smalltalk.Package.klass);
+
+smalltalk.addMethod(
+unescape('_init_'),
+smalltalk.method({
+selector: unescape('init%3A'),
+category: 'loading-storing',
+fn: function (aPackageName){
+var self=this;
+(function($rec){smalltalk.send($rec, "_do_", [(function(each){return smalltalk.init(each);})]);return smalltalk.send($rec, "_do_", [(function(each){return smalltalk.send(each, "_initialize", []);})]);})(smalltalk.send(smalltalk.send((typeof smalltalk == 'undefined' ? nil : smalltalk), "_classes", []), "_select_", [(function(each){return each.pkg.pkgName == aPackageName;})]));
+return self;},
+args: ["aPackageName"],
+source: unescape('init%3A%20aPackageName%0A%09%28smalltalk%20classes%20select%3A%20%5B%20%3Aeach%20%7C%20%3Ceach.pkg.pkgName%20%3D%3D%20aPackageName%3E%20%5D%29%0A%09%09do%3A%20%5B%20%3Aeach%20%7C%20%3Csmalltalk.init%28each%29%3E%20%5D%3B%0A%09%09do%3A%20%5B%20%3Aeach%20%7C%20each%20initialize%20%5D'),
+messageSends: ["do:", "initialize", "select:", "classes"],
+referencedClasses: []
+}),
+smalltalk.Package.klass);
+
 
 smalltalk.addClass('Number', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.addMethod(

+ 23 - 6
js/amber.js

@@ -6,7 +6,6 @@
   })
 */
 
-
 amber = (function() {
   var that = {};
 
@@ -22,6 +21,17 @@ amber = (function() {
   var localPackages;
   var spec;
 
+  that.toggleIDE = function() {
+    if ($('#jtalk').length == 0) {
+      smalltalk.Browser._open();
+    } else if ($('#jtalk').is(':visible')) {
+      smalltalk.TabManager._current()._close();
+    } else {
+      smalltalk.TabManager._current()._open();
+    }
+    return false;
+  }
+
   that.load = function(obj) {
     spec = obj || {};
 
@@ -30,6 +40,12 @@ amber = (function() {
     deploy = spec.deploy || false;
     debug = spec.debug || false;
 
+    // When debug is turned on, logs are written to the console,
+    // and the user will be prompted before they leave the page.
+    if (debug) {
+      window.onbeforeunload = function(){ return 'You will loose all code that you have not committed'; }
+    }
+
     // Allow loading default Amber files from a different location
     // e.g. http://amber-lang.net/amber/
     if (spec.home) home = spec.home;
@@ -85,7 +101,9 @@ amber = (function() {
     // Always load all local packages
     for (name in localPackages) {
       log('Local package:  ' + name);
-      localStorageSource.push(localPackages[name]);
+      var sourceCode = unescape(localPackages[name]);
+      sourceCode += "\nsmalltalk.Package._init_('"+name+"')";
+      localStorageSource.push(sourceCode);
     }
 
     // Be sure to setup & initialize smalltalk classes
@@ -151,8 +169,8 @@ amber = (function() {
   function loadIDEDependencies() {
     loadJS('lib/jQuery/jquery.textarea.js');
     loadJS('lib/CodeMirror/codemirror.js');
-    loadCSS('lib/CodeMirror/codemirror.css', 'js');
     loadJS('lib/CodeMirror/smalltalk.js');
+    loadCSS('lib/CodeMirror/codemirror.css', 'js');
     loadCSS('lib/CodeMirror/amber.css', 'js');
   };
 
@@ -208,6 +226,5 @@ amber = (function() {
   return that;
 })();
 
-window.loadAmber = function(spec) {
-  amber.load(spec);
-}
+window.loadAmber = amber.load;
+window.toggleAmberIDE = amber.toggleIDE;

+ 13 - 0
st/Additional-Examples.st

@@ -0,0 +1,13 @@
+Smalltalk current createPackage: 'Additional-Examples' properties: #{}!
+Object subclass: #ClassInitializationExample
+	instanceVariableNames: ''
+	category: 'Additional-Examples'!
+!ClassInitializationExample commentStamp!
+This class will pop up an alert when it is loaded into Amber.!
+
+!ClassInitializationExample class methodsFor: 'initialization'!
+
+initialize
+	window alert: 'Hello from inside the ', self printString , ' initialize method.'
+! !
+

+ 28 - 1
st/Kernel-Objects.st

@@ -423,7 +423,11 @@ Packages are manipulated through "Smalltalk current", like for example finding o
 
 A Package differs slightly from a Monticello package which can span multiple class categories using a naming convention based on hyphenation. But just as in Monticello a Package supports "class extensions" so a Package
 can define behaviors in foreign classes using a naming convention for method categories where the category starts with an asterisk and then the name of the owning package follows. This can easily be seen in for example class
-String where the method category "*IDE" defines #inspectOn: which thus is a method belonging to the IDE package.!
+String where the method category "*IDE" defines #inspectOn: which thus is a method belonging to the IDE package.
+
+You can fetch a package from the server:
+
+	Package fetch: 'Additional-Examples'!
 
 !Package methodsFor: 'accessing'!
 
@@ -543,6 +547,29 @@ resetCommitPaths
         defaultCommitPathSt := nil.
 ! !
 
+!Package class methodsFor: 'loading-storing'!
+
+fetch: aPackageName prefix: aPrefix
+	jQuery getScript: (aPrefix , aPackageName , '.js') onSuccess: [ Package init: aPackageName ]
+!
+
+fetch: aPackageName
+	self fetch: aPackageName prefix: self defaultCommitPathJs, '/'
+!
+
+commitToLocalStorage: aPackageName
+	| key sourceCode |
+	key := 'smalltalk.packages.' , aPackageName.
+	sourceCode := Exporter new exportPackage: aPackageName.
+	<localStorage[key] = escape(sourceCode)>
+!
+
+init: aPackageName
+	(smalltalk classes select: [ :each | <each.pkg.pkgName == aPackageName> ])
+		do: [ :each | <smalltalk.init(each)> ];
+		do: [ :each | each initialize ]
+! !
+
 !Package class methodsFor: 'not yet classified'!
 
 named: aPackageName