Skip to content
Browse files

europython merge

git-svn-id: https://pyjamas.svn.sourceforge.net/svnroot/pyjamas/trunk@811 7a2bd370-bda8-463c-979e-2900ccfb811e
  • Loading branch information...
1 parent f30e44c commit 30fb40073ba05652ad0ba8f811f0040f5a45f836 bernddorn committed Jul 7, 2009
Showing with 5,151 additions and 241 deletions.
  1. +37 −5 CHANGELOG
  2. +19 −0 TODO
  3. +6 −10 bootstrap.py
  4. +18 −0 dev/README.txt
  5. +52 −0 dev/bootstrap.py
  6. +13 −0 dev/buildout.cfg
  7. +2 −2 examples/formpanel/build.sh
  8. +1 −3 examples/gridtest/build.sh
  9. +7 −3 examples/helloworld/Hello.py
  10. +2 −2 examples/helloworld/build.sh
  11. +1 −1 examples/helloworld/public/Hello.html
  12. +2 −2 examples/libtest/BoolTest.py
  13. +0 −1 examples/libtest/JSOTest.py
  14. +3 −0 examples/libtest/ListTest.py
  15. +2 −1 examples/libtest/MD5Test.py
  16. +60 −61 examples/libtest/SetTest.py
  17. +1 −2 examples/libtest/UnitTest.py
  18. +1 −1 examples/libtest/build.sh
  19. +2 −2 examples/libtest/write.py
  20. 0 library/{webkit.py → __browser__/__init__.py}
  21. 0 library/{pyjamas/platform/Canvas2DPyJS.py → __browser__/pyjamas/Canvas2D.py}
  22. 0 library/{pyjamas/platform/CookiesPyJS.py → __browser__/pyjamas/Cookies.py}
  23. 0 library/{pyjamas/platform/DOMPyJS.py → __browser__/pyjamas/DOM.py}
  24. 0 library/{pyjamas/platform/HTTPRequestPyJS.py → __browser__/pyjamas/HTTPRequest.py}
  25. 0 library/{pyjamas/platform/HistoryPyJS.py → __browser__/pyjamas/History.py}
  26. 0 library/{pyjamas/platform/JSONServicePyJS.py → __browser__/pyjamas/JSONService.py}
  27. 0 library/{pyjamas/platform/TimerPyJS.py → __browser__/pyjamas/Timer.py}
  28. 0 library/{pyjamas/platform/WindowPyJS.py → __browser__/pyjamas/Window.py}
  29. 0 library/{urllib.py → __browser__/pyjamas/__init__.py}
  30. 0 library/{pyjamas/platform/loaderPyJS.py → __browser__/pyjamas/loader.py}
  31. 0 library/{pyjamas/ui/platform/FormPanelPyJS.py → __browser__/pyjamas/ui/FormPanel.py}
  32. 0 library/{traceback.py → __browser__/pyjamas/ui/__init__.py}
  33. 0 library/{string.py → __ie6__/__init__.py}
  34. 0 library/{pyjamas/platform/DOMIE6.py → __ie6__/pyjamas/DOM.py}
  35. 0 library/{pyjamas/platform/HTTPRequestIE6.py → __ie6__/pyjamas/HTTPRequest.py}
  36. 0 library/{pyjamas/platform/HistoryIE6.py → __ie6__/pyjamas/History.py}
  37. 0 library/{pyjamas/platform/LocationOpera.py → __ie6__/pyjamas/Location.py}
  38. 0 library/{pyjamas/platform/__pyjamas__PyJS.py → __ie6__/pyjamas/__init__.py}
  39. 0 library/{pyjamas/ui/platform/FormPanelIE6.py → __ie6__/pyjamas/ui/FormPanel.py}
  40. 0 library/{pyjamas/ui/platform/PopupPanelIE6.py → __ie6__/pyjamas/ui/PopupPanel.py}
  41. 0 library/{pyjamas/ui/platform/TextAreaIE6.py → __ie6__/pyjamas/ui/TextArea.py}
  42. 0 library/{pyjamas/ui/platform/TextBoxBaseIE6.py → __ie6__/pyjamas/ui/TextBoxBase.py}
  43. 0 library/{pyjamas/ui/platform/horizsplitpanelIE6.py → __ie6__/pyjamas/ui/horizsplitpanel.py}
  44. 0 library/{os.py → __mozilla__/__init__.py}
  45. 0 library/{pyjamas/platform/DOMMozilla.py → __mozilla__/pyjamas/DOM.py}
  46. 0 library/{hula.py → __mozilla__/pyjamas/__init__.py}
  47. 0 library/{gobject.py → __oldmoz__/__init__.py}
  48. 0 library/{pyjamas/platform/DOMOldMoz.py → __oldmoz__/pyjamas/DOM.py}
  49. +118 −0 library/__oldmoz__/pyjamas/DOMOldMoz.py
  50. 0 library/{Cookie.py → __oldmoz__/pyjamas/__init__.py}
  51. 0 library/{pyjamas/ui/platform/FocusOldMoz.py → __oldmoz__/pyjamas/ui/Focus.py}
  52. 0 library/__oldmoz__/pyjamas/ui/__init__.py
  53. 0 library/__opera__/__init__.py
  54. 0 library/{pyjamas/platform/DOMOpera.py → __opera__/pyjamas/DOM.py}
  55. 0 library/{pyjamas/platform/LocationIE6.py → __opera__/pyjamas/Location.py}
  56. 0 library/__opera__/pyjamas/__init__.py
  57. 0 library/{pyjamas/ui/platform/FocusOpera.py → __opera__/pyjamas/ui/Focus.py}
  58. 0 library/{pyjamas/ui/platform/FormPanelOpera.py → __opera__/pyjamas/ui/FormPanel.py}
  59. 0 library/__opera__/pyjamas/ui/__init__.py
  60. 0 library/__safari__/__init__.py
  61. 0 library/{pyjamas/platform/DOMSafari.py → __safari__/pyjamas/DOM.py}
  62. 0 library/{pyjamas/platform/HistorySafari.py → __safari__/pyjamas/History.py}
  63. 0 library/__safari__/pyjamas/__init__.py
  64. 0 library/{pyjamas/ui/platform/FocusSafari.py → __safari__/pyjamas/ui/Focus.py}
  65. 0 library/__safari__/pyjamas/ui/__init__.py
  66. 0 library/{pyjamas/ui/platform/horizsplitpanelSafari.py → __safari__/pyjamas/ui/horizsplitpanel.py}
  67. +2 −106 pyjs/build.py
  68. +18 −0 pyjs/setup.py
  69. +10 −0 pyjs/src/pyjs/__init__.py
  70. +103 −0 pyjs/src/pyjs/boilerplate/all.cache.html
  71. +86 −0 pyjs/src/pyjs/boilerplate/home.nocache.html
  72. +215 −0 pyjs/src/pyjs/browser.py
  73. +167 −0 pyjs/src/pyjs/browser.txt
  74. +18 −0 pyjs/src/pyjs/builtin/__mozilla__/pyjslib.py
  75. +1 −0 pyjs/src/pyjs/builtin/__spidermonkey__/__init__.py
  76. +5 −0 pyjs/src/pyjs/builtin/__spidermonkey__/pyjslib.py
  77. +375 −0 pyjs/src/pyjs/builtin/public/_pyjs.js
  78. +171 −0 pyjs/src/pyjs/builtin/public/bootstrap.js
  79. 0 {library → pyjs/src/pyjs/builtin/public}/sprintf.js
  80. +542 −33 {library → pyjs/src/pyjs/builtin}/pyjslib.py
  81. 0 {library/builtins → pyjs/src/pyjs/lib}/math.py
  82. 0 {library → pyjs/src/pyjs/lib}/md5.py
  83. +0 −1 {library/builtins → pyjs/src/pyjs/lib}/sets.py
  84. +2 −5 {library → pyjs/src/pyjs/lib}/sys.py
  85. 0 {library → pyjs/src/pyjs/lib}/time.py
  86. +182 −0 pyjs/src/pyjs/linker.py
  87. +128 −0 pyjs/src/pyjs/sm.py
  88. +51 −0 pyjs/src/pyjs/sm.txt
  89. +23 −0 pyjs/src/pyjs/testing.py
  90. +16 −0 pyjs/src/pyjs/tests.py
  91. +2,476 −0 pyjs/src/pyjs/translator.py
  92. +179 −0 pyjs/src/pyjs/translator.txt
  93. +34 −0 pyjs/src/pyjs/util.py
View
42 CHANGELOG
@@ -1,6 +1,38 @@
Changes made to Pyjamas since 0.5p1
-----------------------------------
+ * huge refactoring, with incompatible changes, see TODO
+
+ * the translator and the linker are now split
+
+ * python packages are now supported
+
+ * translation (not linking) is done on a per-file basis like in
+ python, no requirement for existing imports anymore
+
+ * overrides are searched for in a namespace package e.g
+ (__mozilla__), this means we can place overrides anywhere in the
+ pyjs.path
+
+ * platforms can inherit from others e.g. spidermonkey inherits from
+ mozilla (multioverride - no need for runner specific special
+ translation like the PyJS hack)
+
+ * public folders are looked up in any directory where a module lives
+ - this means the data_directory option is gone
+
+ * pyjs/builtin/public now holds required bootstrap script files
+
+ * there is a dev directory where all scripts from pyjs are now
+ generated via normal setup.py and buildout
+
+ * in the dev directory a test script tests the translator, browser-
+ and spidermonkey-linker, the spidermonkey linker test actually runs
+ examples/libtest
+
+ * builtins now live in pyjs/builtin, those builtins (e.g. pyjslib)
+ are transparent from python
+
* Patch from Stefan Schwarzer to replace != None with is not None
and == None with is None, general clean-up.
@@ -31,7 +63,7 @@
* Moved top-level option and track variable to safe variable $pyjs
- * Repaired pyv8 code
+ * Repaired pyv8 code
* Namespace safe module imports
@@ -45,12 +77,12 @@
* Added support for toplevel conditional import/from-import
- * Added name mapping to protect javascript reserved function methods
+ * Added name mapping to protect javascript reserved function methods
and reserved local variables (e.g. .name/.prototype, this/arguments)
* Revised name (variable/class/function/...) lookup
- * Extended compile option support for commandline building and
+ * Extended compile option support for commandline building and
compiling and for function / method decorators
* Added __repr__() and toString() to list/tuple/dict
@@ -110,7 +142,7 @@
* Added argument checking on all functions/methods
* Added kwarg parsing on all generated functions
-
+
* Added parital implementation of super() function
* Changed Javascript backend for generating classes
@@ -164,7 +196,7 @@
* Add support for Google Gears (Database)
- * Completed DisclosurePanel port
+ * Completed DisclosurePanel port
Changes made to Pyjamas since 0.5
View
19 TODO
@@ -0,0 +1,19 @@
+=====
+Todos
+=====
+
+After the europython merge we have still some things to change.
+
+- fix all example build scripts
+
+- test all examples
+
+- move all python library modules implemented for js into pyjs/lib
+
+- move all builtin modules implemented for js into pyjs/builtin
+
+- fix v8 runner (implement linker)
+
+- evtl. fix spidermonkey runner, but there is a linker that already
+ uses the js commandline interface from spidermonkey
+
View
16 bootstrap.py
@@ -10,20 +10,16 @@
import os
import sys
sys.path[0:0] = [
- r'%s',
+os.path.join(r'%s', 'pyjs', 'src'),
]
-
import pyjs
pyjs.path += [os.path.join(pyjspth, 'library'),
-os.path.join(pyjspth, 'library', 'builtins'),
os.path.join(pyjspth, 'addons'),
]
-sys.argv.extend(['-D', pyjspth])
-
-import pyjs.build
+import pyjs.browser
if __name__ == '__main__':
- pyjs.build.main()
+ pyjs.browser.build_script()
"""
pyjscompile = """#!%s
@@ -33,14 +29,14 @@
import os
import sys
sys.path[0:0] = [
- r'%s',
+ r'%s/pyjs/src',
]
-import pyjs
+import pyjs.translator
pyjs.path += [os.path.join(pyjspth, 'library')]
if __name__ == '__main__':
- pyjs.main()
+ pyjs.translator.main()
"""
pyjdinit = """
View
18 dev/README.txt
@@ -0,0 +1,18 @@
+=================
+Development setup
+=================
+
+To run tests do the following in this directory.
+
+python2.5 bootstrap.py
+./bin/buildout
+./bin/test
+
+Note that the spidermonkey test requires that the "js" executable is
+in the PATH. The LibTests in the example directory are also run and
+checked for javascript exceptions that are not catched.
+
+Also a builder script gets created. see:
+
+./bin/build --help
+
View
52 dev/bootstrap.py
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
View
13 dev/buildout.cfg
@@ -0,0 +1,13 @@
+[buildout]
+develop = ../pyjs
+parts = test scripts
+
+[test]
+recipe = zc.recipe.testrunner
+defaults = ['--auto-color']
+eggs = pyjs [test]
+
+
+[scripts]
+recipe = zc.recipe.egg:script
+eggs = pyjs
View
4 examples/formpanel/build.sh
@@ -1,4 +1,4 @@
#!/bin/sh
options="$*"
-if [ -z $options ] ; then options="-O";fi
-../../bin/pyjsbuild $options FormPanelExample.py
+#if [ -z $options ] ; then options="-O";fi
+../../bin/pyjsbuild $options FormPanelExample
View
4 examples/gridtest/build.sh
@@ -1,4 +1,2 @@
#!/bin/sh
-options="$*"
-if [ -z $options ] ; then options="-O";fi
-../../bin/pyjsbuild $options GridTest.py
+../../bin/pyjsbuild $@ GridTest
View
10 examples/helloworld/Hello.py
@@ -1,13 +1,17 @@
-import pyjd # this is dummy in pyjs.
+#import pyjd # this is dummy in pyjs.
from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.Button import Button
from pyjamas import Window
+#from __pyjamas__ import JS
def greet(fred):
+ print "greet button"
Window.alert("Hello, AJAX!")
if __name__ == '__main__':
- pyjd.setup("public/Hello.html")
+ #pyjd.setup("public/Hello.html")
+ print "hoschi"
+ #print "-----root-------", RootPanel
b = Button("Click me", greet)
RootPanel().add(b)
- pyjd.run()
+ #pyjd.run()
View
4 examples/helloworld/build.sh
@@ -3,5 +3,5 @@
# and buildout in order to make pyjsbuild
options="$*"
-if [ -z $options ] ; then options="-O";fi
-../../bin/pyjsbuild $options Hello.py
+#if [ -z $options ] ; then options="-O";fi
+../../bin/pyjsbuild --print-statements $options Hello
View
2 examples/helloworld/public/Hello.html
@@ -11,6 +11,6 @@
<pre>
some text demonstrating static HTML here.
</pre>
- <script language="javascript" src="pygwt.js"></script>
+ <script language="javascript" src="bootstrap.js"></script>
</body>
</html>
View
4 examples/libtest/BoolTest.py
@@ -32,7 +32,7 @@ def getName(self):
return "Bool"
def testBaseTypes(self):
-
+ print "in testBaseTypes"
# meta test first
self.assertTrue(True)
self.assertFalse(False)
@@ -83,7 +83,7 @@ def testWhileStatement(self):
while([]):
self.fail("Empty lists should not evaluate to True in While")
break;
-
while([1]):
return
self.fail("None-empty lists should evaluate to True in While")
+
View
1 examples/libtest/JSOTest.py
@@ -1,5 +1,4 @@
from UnitTest import UnitTest
-import pyjslib
class Foo:pass
View
3 examples/libtest/ListTest.py
@@ -235,6 +235,9 @@ def testIndex(self):
try:
l.index(200000)
except ValueError, e:
+ print "------------------------"
+ print str(e)
+ print "------------------------"
self.assertTrue(str(e) == "list.index(x): x not in list",
"ValueError exception has incorrect message")
else:
View
3 examples/libtest/MD5Test.py
@@ -11,7 +11,8 @@
# from md5 import md5
from md5 import md5
-if sys.platform in ['mozilla', 'ie6', 'opera', 'oldmoz', 'safari']:
+if sys.platform in ['mozilla', 'ie6', 'opera', 'oldmoz',
+ 'safari', 'spidermonkey']:
def hexstr(s):
h = '0123456789abcdef'
View
121 examples/libtest/SetTest.py
@@ -15,68 +15,67 @@
class SetTest(UnitTest):
- def __init__(self):
- UnitTest.__init__(self)
-
- def getName(self):
- return "Set"
-
- def testInit(self):
- value = Set(['a', 'b', 'c'])
-
- self.assertTrue('b' in value)
- self.assertTrue('d' not in value)
-
- def testAdd(self):
- value = Set()
- value.add("a")
- value.add("b")
- value.add("a")
-
- self.assertTrue('a' in value)
- self.assertTrue('c' not in value)
- self.assertTrue(len(value) is 2)
-
- def testRemove(self):
- value = Set(['a', 'b', 'c'])
- value.remove('a')
-
- self.assertTrue('a' not in value)
- self.assertTrue('b' in value)
-
- def testIter(self):
- items = ['a', 'b', 'c']
- value = Set(items)
-
- for i in value:
- items.remove(i)
-
- self.assertTrue(len(items) is 0)
-
- def testAddObject(self):
- v1 = DummyClass('a')
- v2 = DummyClass('b')
- v3 = DummyClass('b')
- v4 = DummyClass('c')
- items = [v1, v2, v3]
-
- value = Set()
- value.add(v1)
- value.add(v2)
- value.add(v1)
- value.add(v3)
-
- self.assertTrue(v1 in value)
- self.assertTrue(v2 in value)
- self.assertTrue(v3 in value)
- self.assertTrue(v4 not in value)
- self.assertTrue(len(value) is 3)
+ def __init__(self):
+ UnitTest.__init__(self)
+
+ def getName(self):
+ return "Set"
+
+ def testInit(self):
+ value = Set(['a', 'b', 'c'])
+
+ self.assertTrue('b' in value)
+ self.assertTrue('d' not in value)
+
+ def testAdd(self):
+ value = Set()
+ value.add("a")
+ value.add("b")
+ value.add("a")
+
+ self.assertTrue('a' in value)
+ self.assertTrue('c' not in value)
+ self.assertTrue(len(value) is 2)
+
+ def testRemove(self):
+ value = Set(['a', 'b', 'c'])
+ value.remove('a')
+
+ self.assertTrue('a' not in value)
+ self.assertTrue('b' in value)
+
+ def testIter(self):
+ items = ['a', 'b', 'c']
+ value = Set(items)
+
+ for i in value:
+ items.remove(i)
+
+ self.assertTrue(len(items) is 0)
+
+ def testAddObject(self):
+ v1 = DummyClass('a')
+ v2 = DummyClass('b')
+ v3 = DummyClass('b')
+ v4 = DummyClass('c')
+
+ value = Set()
+ value.add(v1)
+ value.add(v2)
+ value.add(v1)
+ value.add(v3)
+
+ self.assertTrue(v1 in value)
+ self.assertTrue(v2 in value)
+ self.assertTrue(v3 in value)
+ self.assertTrue(v4 not in value)
+ self.assertTrue(len(value) is 3)
class DummyClass:
- def __init__(self, value):
- self.value = value
-
- def getValue(self):
- return self.value
+ def __init__(self, value):
+ self.value = value
+
+ def getValue(self):
+ return self.value
View
3 examples/libtest/UnitTest.py
@@ -67,6 +67,7 @@ def fail(self, msg=None):
title="<b>" + self.getNameFmt("Test failed") + "</b>"
writebr(title + msg)
if sys.platform in ['mozilla', 'ie6', 'opera', 'oldmoz', 'safari']:
+ from __pyjamas__ import JS
JS("""if (typeof console != 'undefined') {
console.error(msg)
console.trace()
@@ -123,8 +124,6 @@ def displayStats(self):
fg_colour="#000000"
tests_passed=self.tests_completed - self.tests_failed
-
-
if sys.platform in ['mozilla', 'ie6', 'opera', 'oldmoz', 'safari']:
output="<table cellpadding=4 width=100%><tr><td bgcolor='" + bg_colour + "'><font face='arial' size=4 color='" + fg_colour + "'><b>"
else:
View
2 examples/libtest/build.sh
@@ -1,2 +1,2 @@
#!/bin/sh
-../../bin/pyjsbuild $options LibTest.py
+../../bin/pyjsbuild $options LibTest
View
4 examples/libtest/write.py
@@ -23,10 +23,10 @@ def init_web():
$doc.body.appendChild(write. element); """)
def write_std(text):
- sys.stdout.write(text)
+ print text,
def writebr_std(text):
- sys.stdout.write(text + "\n")
+ print text
if sys.platform in ['mozilla', 'ie6', 'opera', 'oldmoz', 'safari']:
init_web()
View
0 library/webkit.py → library/__browser__/__init__.py
File renamed without changes.
View
0 library/pyjamas/platform/Canvas2DPyJS.py → library/__browser__/pyjamas/Canvas2D.py
File renamed without changes.
View
0 library/pyjamas/platform/CookiesPyJS.py → library/__browser__/pyjamas/Cookies.py
File renamed without changes.
View
0 library/pyjamas/platform/DOMPyJS.py → library/__browser__/pyjamas/DOM.py
File renamed without changes.
View
0 library/pyjamas/platform/HTTPRequestPyJS.py → library/__browser__/pyjamas/HTTPRequest.py
File renamed without changes.
View
0 library/pyjamas/platform/HistoryPyJS.py → library/__browser__/pyjamas/History.py
File renamed without changes.
View
0 library/pyjamas/platform/JSONServicePyJS.py → library/__browser__/pyjamas/JSONService.py
File renamed without changes.
View
0 library/pyjamas/platform/TimerPyJS.py → library/__browser__/pyjamas/Timer.py
File renamed without changes.
View
0 library/pyjamas/platform/WindowPyJS.py → library/__browser__/pyjamas/Window.py
File renamed without changes.
View
0 library/urllib.py → library/__browser__/pyjamas/__init__.py
File renamed without changes.
View
0 library/pyjamas/platform/loaderPyJS.py → library/__browser__/pyjamas/loader.py
File renamed without changes.
View
0 library/pyjamas/ui/platform/FormPanelPyJS.py → library/__browser__/pyjamas/ui/FormPanel.py
File renamed without changes.
View
0 library/traceback.py → library/__browser__/pyjamas/ui/__init__.py
File renamed without changes.
View
0 library/string.py → library/__ie6__/__init__.py
File renamed without changes.
View
0 library/pyjamas/platform/DOMIE6.py → library/__ie6__/pyjamas/DOM.py
File renamed without changes.
View
0 library/pyjamas/platform/HTTPRequestIE6.py → library/__ie6__/pyjamas/HTTPRequest.py
File renamed without changes.
View
0 library/pyjamas/platform/HistoryIE6.py → library/__ie6__/pyjamas/History.py
File renamed without changes.
View
0 library/pyjamas/platform/LocationOpera.py → library/__ie6__/pyjamas/Location.py
File renamed without changes.
View
0 library/pyjamas/platform/__pyjamas__PyJS.py → library/__ie6__/pyjamas/__init__.py
File renamed without changes.
View
0 library/pyjamas/ui/platform/FormPanelIE6.py → library/__ie6__/pyjamas/ui/FormPanel.py
File renamed without changes.
View
0 library/pyjamas/ui/platform/PopupPanelIE6.py → library/__ie6__/pyjamas/ui/PopupPanel.py
File renamed without changes.
View
0 library/pyjamas/ui/platform/TextAreaIE6.py → library/__ie6__/pyjamas/ui/TextArea.py
File renamed without changes.
View
0 ...ary/pyjamas/ui/platform/TextBoxBaseIE6.py → library/__ie6__/pyjamas/ui/TextBoxBase.py
File renamed without changes.
View
0 ...pyjamas/ui/platform/horizsplitpanelIE6.py → ...ary/__ie6__/pyjamas/ui/horizsplitpanel.py
File renamed without changes.
View
0 library/os.py → library/__mozilla__/__init__.py
File renamed without changes.
View
0 library/pyjamas/platform/DOMMozilla.py → library/__mozilla__/pyjamas/DOM.py
File renamed without changes.
View
0 library/hula.py → library/__mozilla__/pyjamas/__init__.py
File renamed without changes.
View
0 library/gobject.py → library/__oldmoz__/__init__.py
File renamed without changes.
View
0 library/pyjamas/platform/DOMOldMoz.py → library/__oldmoz__/pyjamas/DOM.py
File renamed without changes.
View
118 library/__oldmoz__/pyjamas/DOMOldMoz.py
@@ -0,0 +1,118 @@
+def compare(elem1, elem2):
+ JS("""
+ if (!elem1 && !elem2) {
+ return true;
+ } else if (!elem1 || !elem2) {
+ return false;
+ }
+ if (!elem1.isSameNode) {
+ return (elem1 == elem2);
+ }
+ return (elem1.isSameNode(elem2));
+ """)
+
+def eventGetButton(evt):
+ JS("""
+ var button = evt.button;
+ if(button == 0) {
+ return 1;
+ } else if (button == 1) {
+ return 4;
+ } else {
+ return button;
+ }
+ """)
+
+def getAbsoluteLeft(elem):
+ JS("""
+ var left = 0;
+ var parent = elem;
+
+ while (parent) {
+ if (parent.scrollLeft > 0) {
+ left = left - parent.scrollLeft;
+ }
+ parent = parent.parentNode;
+ }
+ while (elem) {
+ left = left + elem.offsetLeft;
+ elem = elem.offsetParent;
+ }
+
+ return left + $doc.body.scrollLeft + $doc.documentElement.scrollLeft;
+ """)
+
+def getAbsoluteTop(elem):
+ JS("""
+ var top = 0;
+ var parent = elem;
+ while (parent) {
+ if (parent.scrollTop > 0) {
+ top -= parent.scrollTop;
+ }
+ parent = parent.parentNode;
+ }
+
+ while (elem) {
+ top += elem.offsetTop;
+ elem = elem.offsetParent;
+ }
+ return top + $doc.body.scrollTop + $doc.documentElement.scrollTop;
+ """)
+
+def getChildIndex(parent, child):
+ JS("""
+ var count = 0, current = parent.firstChild;
+ while (current) {
+ if (! current.isSameNode) {
+ if (current == child) {
+ return count;
+ }
+ }
+ else if (current.isSameNode(child)) {
+ return count;
+ }
+ if (current.nodeType == 1) {
+ ++count;
+ }
+ current = current.nextSibling;
+ }
+ return -1;
+ """)
+
+def isOrHasChild(parent, child):
+ JS("""
+ while (child) {
+ if ((!parent.isSameNode)) {
+ if (parent == child) {
+ return true;
+ }
+ }
+ else if (parent.isSameNode(child)) {
+ return true;
+ }
+ child = child.parentNode;
+ if (child && child.nodeType != 1) {
+ child = null;
+ }
+ }
+ return false;
+ """)
+
+def releaseCapture(elem):
+ JS("""
+ if ((DOM.sCaptureElem != null) && DOM.compare(elem, DOM.sCaptureElem))
+ DOM.sCaptureElem = null;
+
+ if (!elem.isSameNode) {
+ if (elem == $wnd.__captureElem) {
+ $wnd.__captureElem = null;
+ }
+ }
+ else if (elem.isSameNode($wnd.__captureElem)) {
+ $wnd.__captureElem = null;
+ }
+ """)
+
+
+
View
0 library/Cookie.py → library/__oldmoz__/pyjamas/__init__.py
File renamed without changes.
View
0 library/pyjamas/ui/platform/FocusOldMoz.py → library/__oldmoz__/pyjamas/ui/Focus.py
File renamed without changes.
View
0 library/__oldmoz__/pyjamas/ui/__init__.py
No changes.
View
0 library/__opera__/__init__.py
No changes.
View
0 library/pyjamas/platform/DOMOpera.py → library/__opera__/pyjamas/DOM.py
File renamed without changes.
View
0 library/pyjamas/platform/LocationIE6.py → library/__opera__/pyjamas/Location.py
File renamed without changes.
View
0 library/__opera__/pyjamas/__init__.py
No changes.
View
0 library/pyjamas/ui/platform/FocusOpera.py → library/__opera__/pyjamas/ui/Focus.py
File renamed without changes.
View
0 ...ary/pyjamas/ui/platform/FormPanelOpera.py → library/__opera__/pyjamas/ui/FormPanel.py
File renamed without changes.
View
0 library/__opera__/pyjamas/ui/__init__.py
No changes.
View
0 library/__safari__/__init__.py
No changes.
View
0 library/pyjamas/platform/DOMSafari.py → library/__safari__/pyjamas/DOM.py
File renamed without changes.
View
0 library/pyjamas/platform/HistorySafari.py → library/__safari__/pyjamas/History.py
File renamed without changes.
View
0 library/__safari__/pyjamas/__init__.py
No changes.
View
0 library/pyjamas/ui/platform/FocusSafari.py → library/__safari__/pyjamas/ui/Focus.py
File renamed without changes.
View
0 library/__safari__/pyjamas/ui/__init__.py
No changes.
View
0 ...amas/ui/platform/horizsplitpanelSafari.py → .../__safari__/pyjamas/ui/horizsplitpanel.py
File renamed without changes.
View
108 pyjs/build.py
@@ -22,13 +22,6 @@ def md5sum(tosum):
import re
-usage = """
- usage: %prog [options] <application module name or path>
-
-This is the command line builder for the pyjamas project, which can
-be used to build Ajax applications from Python.
-For more information, see the website at http://pyjs.org/
-"""
# GWT1.2 Impl | GWT1.2 Output | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
# -------------+-----------------------+----------------------+----------------------
@@ -75,103 +68,6 @@ def copy_boilerplate(data_dir, filename, output_dir):
shutil.copy(filename, output_dir)
-# taken and modified from python2.4
-def copytree_exists(src, dst, symlinks=False):
- if not os.path.exists(src):
- return
-
- names = os.listdir(src)
- try:
- os.mkdir(dst)
- except:
- pass
-
- errors = []
- for name in names:
- if name.startswith('CVS'):
- continue
- if name.startswith('.git'):
- continue
- if name.startswith('.svn'):
- continue
-
- srcname = os.path.join(src, name)
- dstname = os.path.join(dst, name)
- try:
- if symlinks and os.path.islink(srcname):
- linkto = os.readlink(srcname)
- os.symlink(linkto, dstname)
- elif isdir(srcname):
- copytree_exists(srcname, dstname, symlinks)
- else:
- shutil.copy2(srcname, dstname)
- except (IOError, os.error), why:
- errors.append((srcname, dstname, why))
- if errors:
- print errors
-
-def check_html_file(source_file, dest_path):
- """ Checks if a base HTML-file is available in the PyJamas
- output directory.
- If the HTML-file isn't available, it will be created.
-
- If a CSS-file with the same name is available
- in the output directory, a reference to this CSS-file
- is included.
-
- If no CSS-file is found, this function will look for a special
- CSS-file in the output directory, with the name
- "pyjamas_default.css", and if found it will be referenced
- in the generated HTML-file.
-
- [thank you to stef mientki for contributing this function]
- """
-
- base_html = """\
-<html>
- <!-- auto-generated html - you should consider editing and
- adapting this to suit your requirements
- -->
- <head>
- <meta name="pygwt:module" content="%(modulename)s">
- %(css)s
- <title>%(title)s</title>
- </head>
- <body bgcolor="white">
- <script language="javascript" src="pygwt.js"></script>
- </body>
-</html>
-"""
-
- filename = os.path.split ( source_file )[1]
- mod_name = os.path.splitext ( filename )[0]
- file_name = os.path.join ( dest_path, mod_name + '.html' )
-
- # if html file in output directory exists, leave it alone.
- if os.path.exists ( file_name ):
- return 0
-
- if os.path.exists (
- os.path.join ( dest_path, mod_name + '.css' ) ) :
- css = "<link rel='stylesheet' href='" + mod_name + ".css'>"
- elif os.path.exists (
- os.path.join ( dest_path, 'pyjamas_default.css' ) ) :
- css = "<link rel='stylesheet' href='pyjamas_default.css'>"
-
- else:
- css = ''
-
- title = 'PyJamas Auto-Generated HTML file ' + mod_name
-
- base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
-
- fh = open (file_name, 'w')
- fh.write (base_html)
- fh.close ()
-
- return 1
-
-
def build(app_name, output, js_includes=(), dynamic=0,
data_dir=None, cache_buster=False,
debug=False,
@@ -371,8 +267,8 @@ def generateAppFiles(data_dir, js_includes, app_name, output, dynamic,
app_translator.translate(None, is_app=False,
debug=debug,
library_modules=['dynamicajax.js',
- '_pyjs.js', 'sys',
- 'pyjslib'])
+ '_pyjs.js', 'sys',
+ 'pyjslib'])
pover[platform].update(app_translator.overrides.items())
for mname, name in app_translator.overrides.items():
pd = overrides.setdefault(mname, {})
View
18 pyjs/setup.py
@@ -0,0 +1,18 @@
+import os
+from setuptools import setup, find_packages, Extension
+
+setup(
+ name="pyjs",
+ version='0.1.0',
+ packages=find_packages('src'),
+ package_dir = {'':'src'},
+ zip_safe = True,
+ include_package_data = False,
+ install_requires = [],
+ extras_require = dict(test=['zope.testing']),
+ entry_points = {'console_scripts':[
+ 'build=pyjs.browser:build_script',
+ 'translate=pyjs.translator:main',
+ 'smbuild=pyjs.sm:build_script',
+ ]},
+ )
View
10 pyjs/src/pyjs/__init__.py
@@ -0,0 +1,10 @@
+import os
+
+path = [os.path.abspath('')]
+
+if os.environ.has_key('PYJSPATH'):
+ for p in os.environ['PYJSPATH'].split(os.pathsep):
+ p = os.path.abspath(p)
+ if os.path.isdir(p):
+ path.append(p)
+
View
103 pyjs/src/pyjs/boilerplate/all.cache.html
@@ -0,0 +1,103 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <!--<script type="text/javascript" src="com.iskitz.ajile.js"></script>-->
+<script>
+var $wnd = parent;
+var $doc = $wnd.document;
+var $moduleName = "%(app_name)s";
+var $pyjs = new Object();
+$pyjs.modules = {};
+$pyjs.modules_hash = {};
+$pyjs.available_modules = %(available_modules)s;
+$pyjs.loaded_modules = {};
+$pyjs.options = new Object();
+$pyjs.options.set_all = function (v) {
+ $pyjs.options.arg_ignore = v;
+ $pyjs.options.arg_count = v;
+ $pyjs.options.arg_is_instance = v;
+ $pyjs.options.arg_instance_type = v;
+ $pyjs.options.arg_kwarg_dup = v;
+ $pyjs.options.arg_kwarg_unexpected_keyword = v;
+ $pyjs.options.arg_kwarg_multiple_values = v;
+}
+$pyjs.options.set_all(true);
+$pyjs.trackstack = [];
+$pyjs.track = {module:'__main__', lineno: 1};
+$pyjs.trackstack.push($pyjs.track);
+
+/*
+ * prepare app system vars
+ */
+$pyjs.platform = '%(platform)s';
+$pyjs.appname = '%(app_name)s';
+$pyjs.loadpath = './';
+
+</script>
+%(app_headers)s
+</head>
+<body onload="if (parent && parent.__pygwt_webModeFrameOnLoad) parent.__pygwt_webModeFrameOnLoad(window, '%(app_name)s');">
+<font face='arial' size='-1'>This script is part of module</font> <code>%(app_name)s</code>
+
+<script><!--
+
+/* early app libs */
+
+%(early_app_libs)s
+
+/* app libs */
+%(app_libs)s
+
+var wait_count = 0;
+
+var onExecutionError = function (exception, name) {
+ var extra = sys.trackstackstr();
+ if (extra == '') {
+ if (exception.name.indexOf('HaltException', 0) < 0) {
+ extra = "\n. Rebuild with pyjsbuild -d for more information.";
+ }
+ } else {
+ extra = "\n" + extra;
+ }
+ alert( "In application " + name + " - " +
+ exception.name + ': ' + exception.message + extra);
+};
+
+function app_imported() {
+ //TODO: check if this is really needed
+ pyjslib('pyjslib');
+ pyjslib.__import__('%(app_name)s', '%(app_name)s', '__main__');
+ return;
+ try {
+ $pyjs.modules['%(app_name)s'] = %(app_name)s('__main__');
+ } catch (exception) {
+ sys.save_exception_stack();
+ onExecutionError(exception, '%(app_name)s');
+ }
+}
+
+function prepare_app() {
+ app_imported();
+ // TODO: we don't need it actually because of the late import call
+}
+
+function pygwtOnLoad(onLoadError, name) {
+ prepare_app();
+ return;
+ if (onLoadError != null)
+ try {
+ prepare_app();
+ } catch (exception) {
+ onLoadError(exception, name);
+ }
+ else {
+ prepare_app();
+ }
+}
+
+--></script>
+
+%(app_body)s
+
+</body>
+</html>
View
86 pyjs/src/pyjs/boilerplate/home.nocache.html
@@ -0,0 +1,86 @@
+<html><head><script>
+
+window["provider$user.agent"] = function() {
+ var ua = navigator.userAgent.toLowerCase();
+ if (ua.indexOf('opera') != -1) {
+ return 'opera';
+ }
+ else if (ua.indexOf('safari') != -1) {
+ return 'safari';
+ }
+ else if (ua.indexOf('msie 6.0') != -1) {
+ return 'ie6';
+ }
+ else if (ua.indexOf('msie 7.0') != -1) {
+ return 'ie6';
+ }
+ else if (ua.indexOf('msie7.0') != -1) {
+ return 'ie6';
+ }
+ else if (ua.indexOf('msie 8.0') != -1) {
+ return 'ie6';
+ }
+ else if (ua.indexOf('mozilla') != -1) {
+ var geckoIdx = ua.indexOf('gecko/');
+ if (geckoIdx == -1)
+ return 'oldmoz';
+ var spaceIdx = ua.indexOf(' ', geckoIdx);
+ if (spaceIdx == -1)
+ spaceIdx = ua.length;
+ var result = /rv:([0-9]+)\.([0-9]+)/.exec(ua);
+ if ((! result || result.length != 3) ||
+ ((parseInt(result[1])<1) ||
+ ((parseInt(result[1])==1) && (parseInt(result[2])<=7))))
+ return 'oldmoz';
+ var version = parseInt(ua.substring(geckoIdx + 6, spaceIdx));
+ if (version < 20051107)
+ return 'oldmoz';
+ return 'mozilla';
+ }
+ return 'unknown';
+}
+;
+
+window["prop$user.agent"] = function() {
+ var v = window["provider$user.agent"]();
+ switch (v) {
+ case "ie6":
+ case "mozilla":
+ case "oldmoz":
+ case "opera":
+ case "safari":
+ return v;
+ default:
+ parent.__pygwt_onBadProperty("%(app_name)s", "user.agent", ['"ie6"', '"mozilla"', '"oldmoz"', '"opera"', '"safari"'], v);
+ throw null;
+ }
+};
+
+function O(a,v) {
+ var answer = O.answers;
+ var i = -1;
+ var n = a.length - 1;
+ while (++i < n) {
+ if (!(a[i] in answer)) {
+ answer[a[i]] = [];
+ }
+ answer = answer[a[i]];
+ }
+ answer[a[n]] = v;
+}
+O.answers = [];
+
+function selectScript() {
+ try {
+ var F;
+ var I = ["true", (F=window["prop$user.agent"],F())];
+
+ %(script_selectors)s
+
+ var strongName = O.answers[I[0]][I[1]];
+ location.replace(strongName);
+ } catch (e) {
+ // intentionally silent on property failure
+ }
+}
+</script></head><body onload='if (parent && parent.__pygwt_webModeFrameOnLoad) selectScript()'><font face='arial' size='-1'>This script is part of module</font> <code>%(app_name)s</code></body></html>
View
215 pyjs/src/pyjs/browser.py
@@ -0,0 +1,215 @@
+import os
+from pyjs import linker
+from pyjs import translator
+from pyjs import util
+from cStringIO import StringIO
+from optparse import OptionParser
+import pyjs
+
+AVAILABLE_PLATFORMS = ('IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla')
+
+BOILERPLATE_PATH = os.path.join(os.path.dirname(__file__), 'boilerplate')
+
+APP_HTML_TEMPLATE = """\
+<html>
+<!-- auto-generated html - you should consider editing and
+adapting this to suit your requirements
+-->
+<head>
+<meta name="pygwt:module" content="%(modulename)s">
+%(css)s
+<title>%(title)s</title>
+</head>
+<body bgcolor="white">
+<script language="javascript" src="bootstrap.js"></script>
+</body>
+</html>
+"""
+
+class BrowserLinker(linker.BaseLinker):
+
+ # we derive from mozilla
+ platform_parents = {
+ 'mozilla':['browser'],
+ 'ie6':['browser'],
+ 'safari':['browser'],
+ 'oldmoz':['browser'],
+ 'opera':['browser']
+ }
+
+ def visit_start(self):
+ super(BrowserLinker, self).visit_start()
+ self.boilerplate_path = None
+ self.js_libs.append('_pyjs.js')
+ self.js_libs.append('sprintf.js')
+ self.merged_public = set()
+
+ def visit_end_platform(self, platform):
+ if not platform:
+ return
+ self._generate_app_file(platform)
+
+ def visit_end(self):
+ html_output_filename = os.path.join(self.output, self.top_module + '.html')
+ if not os.path.exists(html_output_filename):
+ # autogenerate
+ self._create_app_html(html_output_filename)
+ self._create_nocache_html()
+
+ def merge_resources(self, dir_name):
+ if not dir_name in self.merged_public:
+ public_folder = os.path.join(dir_name, 'public')
+ if os.path.exists(public_folder) and os.path.isdir(public_folder):
+ util.copytree_exists(public_folder,
+ self.output)
+ self.merged_public.add(dir_name)
+
+ def find_boilerplate(self, name):
+ if not self.boilerplate_path:
+ self.boilerplate_path = [BOILERPLATE_PATH]
+ module_bp_path = os.path.join(
+ os.path.dirname(self.top_module_path), 'boilerplate')
+ if os.path.isdir(module_bp_path):
+ self.boilerplate_path.insert(0, module_bp_path)
+ for p in self.boilerplate_path:
+ bp = os.path.join(p, name)
+ if os.path.exists(bp):
+ return bp
+ raise RuntimeError("Boilerplate not found %r" % name)
+
+ def read_boilerplate(self, name):
+ f = file(self.find_boilerplate(name))
+ res = f.read()
+ f.close()
+ return res
+
+ def _generate_app_file(self, platform):
+ # TODO: cache busting
+ template = self.read_boilerplate('all.cache.html')
+ out_path = os.path.join(
+ self.output,
+ '.'.join((self.top_module, platform, 'cache.html')))
+ app_code = StringIO()
+ done = self.done[platform]
+ for p in done:
+ f = file(p)
+ app_code.write(f.read())
+ f.close()
+ scripts = ['<script type="text/javascript" src="%s"></script>'%script \
+ for script in self.js_libs]
+ app_body = '\n'.join(scripts)
+ deps = []
+ file_contents = template % dict(
+ app_name = self.top_module,
+ early_app_libs = '',
+ app_libs = app_code.getvalue(),
+ app_body = app_body,
+ platform = platform.lower(),
+ available_modules = self.visited_modules[platform],
+ dynamic = 0,
+ app_headers = ''
+ )
+ out_file = file(out_path, 'w')
+ out_file.write(file_contents)
+ out_file.close()
+
+ def _create_nocache_html(self):
+ # nocache
+ template = self.read_boilerplate('home.nocache.html')
+ out_path = os.path.join(self.output, self.top_module + ".nocache.html")
+ select_tmpl = """O(["true","%%s"],"%s.%%s.cache.html");\n""" % self.top_module
+ script_selectors = StringIO()
+ for platform in self.platforms:
+ script_selectors.write(
+ select_tmpl % (platform, platform))
+ out_file = file(out_path, 'w')
+ out_file.write(template % dict(
+ app_name = self.top_module,
+ script_selectors = script_selectors.getvalue()
+ ))
+ out_file.close()
+
+ def _create_app_html(self, file_name):
+ """ Checks if a base HTML-file is available in the PyJamas
+ output directory.
+ If the HTML-file isn't available, it will be created.
+
+ If a CSS-file with the same name is available
+ in the output directory, a reference to this CSS-file
+ is included.
+
+ If no CSS-file is found, this function will look for a special
+ CSS-file in the output directory, with the name
+ "pyjamas_default.css", and if found it will be referenced
+ in the generated HTML-file.
+ """
+
+ # if html file in output directory exists, leave it alone.
+ if os.path.exists(file_name):
+ return 0
+ if os.path.exists(
+ os.path.join(self.output, self.top_module + '.css' )):
+ css = "<link rel='stylesheet' href='" + self.top_module + ".css'>"
+ elif os.path.exists(
+ os.path.join(self.output, 'pyjamas_default.css' )):
+ css = "<link rel='stylesheet' href='pyjamas_default.css'>"
+ else:
+ css = ''
+
+ title = 'PyJamas Auto-Generated HTML file ' + self.top_module
+
+ base_html = APP_HTML_TEMPLATE % {'modulename': self.top_module,
+ 'title': title, 'css': css}
+
+ fh = open (file_name, 'w')
+ fh.write (base_html)
+ fh.close ()
+ return 1
+
+def build_script():
+ usage = """
+ usage: %prog [options] <application module name
+
+ This is the command line builder for the pyjamas project, which can
+ be used to build Ajax applications from Python.
+ For more information, see the website at http://pyjs.org/
+ """
+ global app_platforms
+ parser = OptionParser(usage = usage)
+ # TODO: compile options
+ translator.add_compile_options(parser)
+ linker.add_linker_options(parser)
+ parser.add_option("-P", "--platforms", dest="platforms",
+ help="platforms to build for, comma-separated")
+ parser.set_defaults(output="output",
+ js_includes=[],
+ library_dirs=[],
+ platforms=(','.join(AVAILABLE_PLATFORMS))
+ )
+ options, args = parser.parse_args()
+ if len(args) != 1:
+ parser.error("incorrect number of arguments")
+
+ top_module = args[0]
+ for d in options.library_dirs:
+ pyjs.path.append(os.path.abspath(d))
+
+ if options.platforms:
+ app_platforms = options.platforms.lower().split(',')
+ print pyjs.path
+
+ translator_arguments=dict(
+ debug=options.debug,
+ print_statements = options.print_statements,
+ function_argument_checking=options.function_argument_checking,
+ attribute_checking=options.attribute_checking,
+ source_tracking=options.source_tracking,
+ line_tracking=options.line_tracking,
+ store_source=options.store_source)
+
+ l = BrowserLinker(top_module,
+ output=options.output,
+ platforms=app_platforms,
+ path=pyjs.path,
+ translator_arguments=translator_arguments)
+ l()
View
167 pyjs/src/pyjs/browser.txt
@@ -0,0 +1,167 @@
+==============
+Browser-Linker
+==============
+
+ >>> from pyjs import browser
+ >>> from pyjs.testing import (
+ ... outputContainsSystemFiles,
+ ... outputContainsPlatforms,
+ ... outputContainsFiles,
+ ... )
+
+Let us generate some python code.
+
+ >>> import tempfile, os, shutil
+ >>> tmp = tempfile.mkdtemp()
+
+ >>> lib_path = os.path.join(tmp, 'lib')
+ >>> pp = os.path.join(lib_path, 'mypackage')
+ >>> os.makedirs(pp)
+ >>> mp = os.path.join(pp, '__init__.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... # package
+ ... """)
+ >>> f.close()
+ >>> mp = os.path.join(pp, 'index.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... def main():
+ ... print 1
+ ... """)
+ >>> f.close()
+
+ >>> output = os.path.join(tmp, 'output')
+ >>> l = browser.BrowserLinker('mypackage.index',
+ ... output=output,
+ ... platforms=['ie6', 'mozilla'],
+ ... path=[lib_path])
+
+ >>> l()
+
+By default the javascript code is compiled to a subdirectory in the
+output directory.
+
+ >>> sorted(os.listdir(os.path.join(output, 'lib')))
+ ['mypackage.index.js', 'mypackage.js', 'pyjslib.__mozilla__.js', 'pyjslib.js']
+
+ >>> out_file = os.path.join(output, 'mypackage.index.ie6.cache.html')
+ >>> print file(out_file).read()
+ <html>...
+ var pyjslib = ...
+ var mypackage = $pyjs.loaded_modules["mypackage"] = function (__mod_name__)...
+
+ >>> outputContainsSystemFiles(output)
+ >>> outputContainsPlatforms(output, 'mypackage.index', ['ie6', 'mozilla'])
+ >>> outputContainsFiles(output, ['mypackage.index.html'])
+
+Let us add another package with some public folder.
+
+ >>> pp = os.path.join(lib_path, 'second_package')
+ >>> os.makedirs(pp)
+ >>> mp = os.path.join(pp, '__init__.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... # package
+ ... """)
+ >>> f.close()
+ >>> mp = os.path.join(pp, 'widget.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... # do something
+ ... """)
+ >>> f.close()
+ >>> p_dir = os.path.join(pp, 'public')
+ >>> os.mkdir(p_dir)
+ >>> mp = os.path.join(p_dir, 'second.css')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... /* some css */
+ ... """)
+ >>> f.close()
+
+ >>> l()
+
+Public folders are merged together, but only if something of the
+package gets imported, which is not the case in this example right
+now.
+
+ >>> outputContainsSystemFiles(output)
+ >>> outputContainsPlatforms(output, 'mypackage.index', ['ie6', 'mozilla'])
+ >>> outputContainsFiles(output, ['mypackage.index.html'])
+
+So let us add an import.
+
+ >>> mp = os.path.join(lib_path, 'mypackage', 'index.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... import second_package.widget
+ ... def main():
+ ... print 1
+ ... if __name__=='__main__':
+ ... main()
+ ... """)
+ >>> f.close()
+
+Now we have the contents of the public folder in our output directory.
+
+ >>> l()
+ >>> print sorted(os.listdir(output))
+ [..., 'second.css'...]
+
+Now we will add a sub module and import it.
+
+ >>> mp = os.path.join(lib_path, 'mypackage', 'util.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... def log(msg):
+ ... print msg
+ ... """)
+ >>> f.close()
+
+ >>> mp = os.path.join(lib_path, 'mypackage', 'index.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... import second_package.widget
+ ... import util
+ ... def main():
+ ... print 1
+ ... if __name__=='__main__':
+ ... main()
+ ... """)
+ >>> f.close()
+
+ >>> l()
+ >>> outputContainsSystemFiles(output)
+ >>> outputContainsPlatforms(output, 'mypackage.index', ['ie6', 'mozilla'])
+ >>> outputContainsFiles(output, ['mypackage.index.html'])
+
+ >>> op = os.path.join(output, 'mypackage.index.ie6.cache.html')
+ >>> f = file(op, 'r')
+ >>> content = f.read()
+ >>> f.close()
+
+ >>> 'mypackage.util.log' in content
+ True
+
+Use an import of an unknown module.
+
+ >>> pp = os.path.join(lib_path, 'mypackage')
+ >>> mp = os.path.join(pp, 'index.py')
+ >>> f = file(mp, 'w')
+ >>> f.write("""
+ ... import unknown.module
+ ... """)
+ >>> f.close()
+ >>> l = browser.BrowserLinker('mypackage.index',
+ ... output=output,
+ ... platforms=['ie6', 'mozilla'],
+ ... path=[lib_path])
+ >>> l()
+ Traceback (most recent call last):
+ RuntimeError: Module 'unknown' found. Dep of {'...
+
+clean up!
+
+ >>> shutil.rmtree(tmp)
+
View
18 pyjs/src/pyjs/builtin/__mozilla__/pyjslib.py
@@ -0,0 +1,18 @@
+
+class List:
+ def index(self, value, start=0):
+ JS("""
+ var result = this.l.indexOf(value, start);
+ if (result >= 0)
+ return result;
+ """)
+ raise ValueError("list.index: " + value + " not in list")
+
+class Tuple:
+ def index(self, value, start=0):
+ JS("""
+ var result = this.l.indexOf(value, start);
+ if (result >= 0)
+ return result;
+ """)
+ raise ValueError("list.index: " + value + " not in list")
View
1 pyjs/src/pyjs/builtin/__spidermonkey__/__init__.py
@@ -0,0 +1 @@
+# spidermonkey builtin ovverrides
View
5 pyjs/src/pyjs/builtin/__spidermonkey__/pyjslib.py
@@ -0,0 +1,5 @@
+
+def printFunc(objs, newline):
+ JS("""
+ print.apply(this, objs);
+ """)
View
375 pyjs/src/pyjs/builtin/public/_pyjs.js
@@ -0,0 +1,375 @@
+
+function pyjs_args_merge(func, star_args, dstar_args, args)
+{
+ var call_args;
+
+ if (star_args) {
+ if (!pyjslib.isIteratable(star_args)) {
+ throw (pyjslib.TypeError(func.__name__ + "() arguments after * must be a sequence" + pyjslib.repr(star_args)));
+ }
+ if (star_args.l != null && star_args.l.constructor == Array) {
+ call_args = args.concat(star_args.l);
+ } else {
+ call_args = Array();
+ var __i = star_args.__iter__();
+ var i = 0;
+ try {
+ while (true) {
+ call_args[i]=__i.next();
+ i++;
+ }
+ } catch (e) {
+ if (e != pyjslib.StopIteration) {
+ throw e;
+ }
+ }
+ call_args = args.concat(call_args);
+ }
+ }
+ else
+ {
+ call_args = args;
+ }
+ if (dstar_args) {
+ if (pyjslib.get_pyjs_classtype(dstar_args) != 'Dict') {
+ throw (pyjslib.TypeError(func.__name__ + "() arguments after ** must be a dictionary " + pyjslib.repr(dstar_args)));
+ }
+ var __i = dstar_args.__iter__();
+ try {
+ while (true) {
+ var i = __i.next();
+ if ($pyjs.options.arg_kwarg_multiple_values && typeof call_args[0][i] != 'undefined') {
+ pyjs__exception_func_multiple_values(func.__name__, i);
+ }
+ call_args[0][i] = dstar_args.__getitem__(i)
+ }
+ } catch (e) {
+ if (e != pyjslib.StopIteration) {
+ throw e;
+ }
+ }
+
+ }
+ return call_args;
+}
+
+function pyjs_kwargs_function_call(func, star_args, dstar_args, args)
+{
+ args = pyjs_args_merge(func, star_args, dstar_args, args);
+ if (func.parse_kwargs) {
+ args = func.parse_kwargs.apply(null, args);
+ } else if ($pyjs.options.arg_kwarg_unexpected_keyword && args.length > 0) {
+ for (var i in args[0]) {
+ pyjs__exception_func_unexpected_keyword(func.__name__, i);
+ }
+ }
+ return func.apply(null, args);
+}
+
+function pyjs_kwargs_method_call(obj, method_name, star_args, dstar_args, args)
+{
+ var method = obj[method_name];
+ args = pyjs_args_merge(method, star_args, dstar_args, args);
+ if (method.parse_kwargs)
+ {
+ args = method.parse_kwargs.apply(obj, args);
+ } else if ($pyjs.options.arg_kwarg_unexpected_keyword && args.length > 0) {
+ for (var i in args[0]) {
+ pyjs__exception_func_unexpected_keyword(method.__name__, i);
+ }
+ }
+ return method.apply(obj, args);
+}
+
+function pyjs__exception_func_param(func_name, minargs, maxargs, nargs) {
+ if (minargs == maxargs) {
+ switch (minargs) {
+ case 0:
+ var msg = func_name + "() takes no arguments (" + nargs + " given)";
+ break;
+ case 1:
+ msg = func_name + "() takes exactly " + minargs + " argument (" + nargs + " given)";
+ break;
+ default:
+ msg = func_name + "() takes exactly " + minargs + " arguments (" + nargs + " given)";
+ };
+ } else if (nargs > maxargs) {
+ if (maxargs == 1) {
+ msg = func_name + "() takes at most " + maxargs + " argument (" + nargs + " given)";
+ } else {
+ msg = func_name + "() takes at most " + maxargs + " arguments (" + nargs + " given)";
+ }
+ } else if (nargs < minargs) {
+ if (minargs == 1) {
+ msg = func_name + "() takes at least " + minargs + " argument (" + nargs + " given)";
+ } else {
+ msg = func_name + "() takes at least " + minargs + " arguments (" + nargs + " given)";
+ }
+ } else {
+ return;
+ }
+ if (typeof pyjslib.TypeError == 'function') {
+ throw pyjslib.TypeError(String(msg));
+ }
+ throw msg
+}
+
+function pyjs__exception_func_multiple_values(func_name, key) {
+ //throw func_name + "() got multiple values for keyword argument '" + key + "'";
+ throw pyjslib.TypeError(String(func_name + "() got multiple values for keyword argument '" + key + "'"));
+}
+
+function pyjs__exception_func_unexpected_keyword(func_name, key) {
+ //throw func_name + "() got an unexpected keyword argument '" + key + "'";
+ throw pyjslib.TypeError(String(func_name + "() got an unexpected keyword argument '" + key + "'"));
+}
+
+function pyjs__exception_func_class_expected(func_name, class_name, instance) {
+ if (typeof instance == 'undefined') {
+ instance = 'nothing';
+ } else if (instance.__is_instance__ == null) {
+ instance = "'"+String(instance)+"'";
+ } else {
+ instance = String(instance);
+ }
+ //throw "unbound method "+func_name+"() must be called with "+class_name+" class as first argument (got "+instance+" instead)";
+ throw pyjslib.TypeError(String("unbound method "+func_name+"() must be called with "+class_name+" class as first argument (got "+instance+" instead)"));
+}
+
+function pyjs__exception_func_instance_expected(func_name, class_name, instance) {
+ if (typeof instance == 'undefined') {
+ instance = 'nothing';
+ } else if (instance.__is_instance__ == null) {
+ instance = "'"+String(instance)+"'";
+ } else {
+ instance = String(instance);
+ }
+ //throw "unbound method "+func_name+"() must be called with "+class_name+" instance as first argument (got "+instance+" instead)";
+ throw pyjslib.TypeError(String("unbound method "+func_name+"() must be called with "+class_name+" instance as first argument (got "+instance+" instead)"));
+}
+
+function pyjs__bind_method(klass, func_name, func, parse_kwargs) {
+ func.__name__ = func.func_name = func_name;
+ func.__class__ = klass;
+ func.prototype = func;
+ if (typeof parse_kwargs != 'undefined') func.parse_kwargs = parse_kwargs;
+ return func;
+}
+function pyjs__instancemethod(klass, func_name, func, parse_kwargs) {
+ var fn = function () {
+ var _this = this;
+ var argstart = 0;
+ if (this.__is_instance__ !== true && arguments.length > 0) {
+ _this = arguments[0];
+ argstart = 1;
+ }
+ var args = new Array(_this);
+ for (var a=argstart;a < arguments.length; a++) args.push(arguments[a]);
+ if ($pyjs.options.arg_is_instance) {
+ if (_this.__is_instance__ === true) {
+ if ($pyjs.options.arg_instance_type) return func.apply(this, args);
+ for (var c in _this.__mro__) {
+ var cls = _this.__mro__[c];
+ if (cls == klass) {
+ return func.apply(this, args);
+ }
+ }
+ }
+ pyjs__exception_func_instance_expected(func_name, klass.__name__, _this);
+ }
+ return func.apply(this, args);
+ };
+ func.__name__ = func.func_name = func_name;
+ func.__class__ = klass;
+ if (typeof parse_kwargs != 'undefined') func.parse_kwargs = parse_kwargs;
+ return fn;
+}
+
+function pyjs__staticmethod(klass, func_name, func, parse_kwargs) {
+ func.__name__ = func.func_name = func_name;
+ func.__class__ = klass;
+ if (typeof parse_kwargs != 'undefined') func.parse_kwargs = parse_kwargs;
+ return func;
+}
+
+function pyjs__classmethod(klass, func_name, func, parse_kwargs) {
+ var fn = function () {
+ if ($pyjs.options.arg_is_instance && this.__is_instance__ !== true && this.__is_instance__ !== false) pyjs__exception_func_instance_expected(func_name, klass.__name__);
+ var args = new Array(this.prototype);
+ for (var a=0;a < arguments.length; a++) args.push(arguments[a]);
+ return func.apply(this, args);
+ };
+ func.__name__ = func.func_name = func_name;
+ func.__class__ = klass;
+ if (typeof parse_kwargs != 'undefined') func.parse_kwargs = parse_kwargs;
+ return fn;
+}
+
+function pyjs__subclasses__(cls_obj) {
+ return cls_obj.__sub_classes__;
+}
+
+function pyjs__mro_merge(seqs) {
+ var res = new Array();
+ var i = 0;
+ var cand = null;
+ function resolve_error(candidates) {
+ //throw "Cannot create a consistent method resolution order (MRO) for bases " + candidates[0].__name__ + ", "+ candidates[1].__name__;
+ throw (pyjslib.TypeError("Cannot create a consistent method resolution order (MRO) for bases " + candidates[0].__name__ + ", "+ candidates[1].__name__));
+ }
+ for (;;) {
+ var nonemptyseqs = new Array();
+ for (var j = 0; j < seqs.length; j++) {
+ if (seqs[j].length > 0) nonemptyseqs.push(seqs[j]);
+ }
+ if (nonemptyseqs.length == 0) return res;
+ i++;
+ var candidates = new Array();
+ for (var j = 0; j < nonemptyseqs.length; j++) {
+ cand = nonemptyseqs[j][0];
+ candidates.push(cand);
+ var nothead = new Array();
+ for (var k = 0; k < nonemptyseqs.length; k++) {
+ for (var m = 1; m < nonemptyseqs[k].length; m++) {
+ if (cand == nonemptyseqs[k][m]) {
+ nothead.push(nonemptyseqs[k]);
+ }
+ }
+ }
+ if (nothead.length != 0)
+ cand = null; // reject candidate
+ else
+ break;
+ }
+ if (cand == null) {
+ resolve_error(candidates);
+ }
+ res.push(cand);
+ for (var j = 0; j < nonemptyseqs.length; j++) {
+ if (nonemptyseqs[j][0] == cand) {
+ nonemptyseqs[j].shift();
+ }
+ }
+ }
+}
+
+function pyjs__class_instance(class_name, module_name) {
+ if (typeof module_name == 'undefined') module_name = typeof __mod_name__ == 'undefined' ? '__main__' : __mod_name__;
+ var cls_fn = function(){
+ var instance = cls_fn.__new__.apply(null, [cls_fn]);
+ if (instance.__init__) {
+ if (instance.__init__.apply(instance, arguments) != null) {
+ //throw '__init__() should return None';
+ throw pyjslib.TypeError('__init__() should return None');
+ }
+ }
+ return instance;
+ }
+ cls_fn.__name__ = class_name;
+ cls_fn.__module__ = module_name;
+ cls_fn.toString = function() { return (this.__is_instance__ === true ? "instance of " : "class ") + (this.__module__?this.__module__ + "." : "") + this.__name__;}
+ return cls_fn;
+}
+
+function pyjs__class_function(cls_fn, prop, bases) {
+ if (typeof cls_fn != 'function') throw "compiler error? pyjs__class_function: typeof cls_fn != 'function'";
+ var class_name = cls_fn.__name__;
+ var class_module = cls_fn.__module__;
+ var base_mro_list = new Array()
+ for (var i = 0; i < bases.length; i++) {
+ if (bases[i].__mro__ != null) {
+ base_mro_list.push(new Array().concat(bases[i].__mro__));
+ }
+ }
+ var __mro__ = pyjs__mro_merge(base_mro_list);
+
+ for (var b = __mro__.length-1; b >= 0; b--) {
+ var base = __mro__[b];
+ for (var p in base) cls_fn[p] = base[p];
+ }
+ for (var p in prop) cls_fn[p] = prop[p];
+
+ if (prop.__new__ == null) {
+ cls_fn.__new__ = pyjs__bind_method(cls_fn, '__new__', function(cls) {
+ var instance = function () {};
+ instance.prototype = arguments[0].prototype;
+ instance = new instance();
+ instance.__dict__ = instance.__class__ = instance;
+ instance.__is_instance__ = true;
+ return instance;
+}, function (__kwargs, cls) {
+ if (typeof cls == 'undefined') {
+ cls=__kwargs.cls;
+ delete __kwargs.cls;
+ } else if ($pyjs.options.arg_kwarg_multiple_values && typeof __kwargs.cls != 'undefined') {
+ pyjs__exception_func_multiple_values('__new__', 'cls');
+ }
+ if ($pyjs.options.arg_kwarg_unexpected_keyword) {
+ for (var i in __kwargs) {
+ pyjs__exception_func_unexpected_keyword('__new__', i);
+ }
+ }
+ var __r = [cls];
+ for (var pyjs__va_arg = 2;pyjs__va_arg < arguments.length;pyjs__va_arg++) {
+ __r.push(arguments[pyjs__va_arg]);
+ }
+
+ return __r;
+});
+
+ }
+ if (cls_fn['__init__'] == null) {
+ cls_fn['__init__'] = pyjs__bind_method(cls_fn, '__init__', function () {
+ if (this.__is_instance__ === true) {
+ var self = this;
+ if ($pyjs.options.arg_count && arguments.length != 0) pyjs__exception_func_param(arguments.callee.__name__, 1, 1, arguments.length+1);
+ } else {
+ var self = arguments[0];
+ if ($pyjs.options.arg_is_instance && self.__is_instance__ !== true) pyjs__exception_func_instance_expected(arguments.callee.__name__, arguments.callee.__class__.__name__, self);
+ if ($pyjs.options.arg_count && arguments.length != 1) pyjs__exception_func_param(arguments.callee.__name__, 1, 1, arguments.length);
+ }
+ if ($pyjs.options.arg_instance_type) {
+ if (arguments.callee !== arguments.callee.__class__[arguments.callee.__name__]) {
+ if (!pyjslib._isinstance(self, arguments.callee.__class__.slice(1))) {
+ pyjs__exception_func_instance_expected(arguments.callee.__name__, arguments.callee.__class__.__name__, self);
+ }
+ }
+ }
+}, function (__kwargs) {
+ var __r = [];
+ return __r;
+});
+ }
+ cls_fn.__name__ = class_name;
+ cls_fn.__module__ = class_module;
+ //cls_fn.__mro__ = pyjslib.List(new Array(cls_fn).concat(__mro__));
+ cls_fn.__mro__ = new Array(cls_fn).concat(__mro__);
+ cls_fn.prototype = cls_fn;
+ cls_fn.__dict__ = cls_fn;
+ cls_fn.__is_instance__ = false;
+ cls_fn.__super_classes__ = bases;
+ cls_fn.__sub_classes__ = new Array();
+ for (var i = 0; i < bases.length; i++) {
+ (bases[i]).__sub_classes__.push(cls_fn);
+ }
+ cls_fn.parse_kwargs = function () {
+ return cls_fn.__init__.parse_kwargs.apply(this, arguments);
+ }
+ return cls_fn;
+}
+
+/* creates a class, derived from bases, with methods and variables */
+function pyjs_type(clsname, bases, methods)
+{
+ var cls_instance = pyjs__class_instance(clsname);
+ var obj = new Object;
+ for (var i in methods) {
+ if (typeof methods[i] == 'function') {
+ obj[i] = pyjs__instancemethod(cls_instance, i, methods[i], methods[i].parse_kwargs);
+ } else {
+ obj[i] = methods[i];
+ }
+ }
+ return pyjs__class_function(cls_instance, obj, bases);
+}
+
View
171 pyjs/src/pyjs/builtin/public/bootstrap.js
@@ -0,0 +1,171 @@
+// this is almost directly taken from Google's GWT which is now open source
+
+var __PYGWT_JS_INCLUDED;
+
+if (!__PYGWT_JS_INCLUDED) {
+ __PYGWT_JS_INCLUDED = true;
+
+var __pygwt_retryWaitMs = 50;
+var __pygwt_moduleNames = [];
+var __pygwt_isHostPageLoaded = false;
+var __pygwt_onLoadError = function (exception, name) {
+
+ alert( name + " " + exception.name + ' ' + exception.message );
+
+};
+
+
+function __pygwt_processMetas() {
+ var metas = document.getElementsByTagName("meta");
+ for (var i = 0, n = metas.length; i < n; ++i) {
+ var meta = metas[i];
+ var name = meta.getAttribute("name");
+ if (name) {
+ if (name == "pygwt:module") {
+ var content = meta.getAttribute("content");
+ if (content) {
+ __pygwt_moduleNames = __pygwt_moduleNames.concat(content);
+ }
+ }
+ }
+ }
+}
+
+
+function __pygwt_forEachModule(lambda) {
+ for (var i = 0; i < __pygwt_moduleNames.length; ++i) {
+ lambda(__pygwt_moduleNames[i]);
+ }
+}
+
+
+// When nested IFRAMEs load, they reach up into the parent page to announce that
+// they are ready to run. Because IFRAMEs load asynchronously relative to the
+// host page, one of two things can happen when they reach up:
+// (1) The host page's onload handler has not yet been called, in which case we
+// retry until it has been called.
+// (2) The host page's onload handler has already been called, in which case the
+// nested IFRAME should be initialized immediately.
+//
+function __pygwt_webModeFrameOnLoad(iframeWindow, name) {
+ var moduleInitFn = iframeWindow.pygwtOnLoad;
+ if (__pygwt_isHostPageLoaded && moduleInitFn) {
+ var old = window.status;
+ window.status = "Initializing module '" + name + "'";
+ try {
+ moduleInitFn(__pygwt_onLoadError, name);
+ } finally {
+ window.status = old;
+ }
+ } else {
+ setTimeout(function() { __pygwt_webModeFrameOnLoad(iframeWindow, name); }, __pygwt_retryWaitMs);
+ }
+}
+
+
+function __pygwt_hookOnLoad() {
+ var oldHandler = window.onload;
+ window.onload = function() {
+ __pygwt_isHostPageLoaded = true;
+ if (oldHandler) {
+ oldHandler();
+ }
+ };
+}
+
+
+// Returns an array that splits the module name from the meta content into
+// [0] the prefix url, if any, guaranteed to end with a slash
+// [1] the dotted module name
+//
+function __pygwt_splitModuleNameRef(moduleName) {
+ var parts = ['', moduleName];
+ var i = moduleName.lastIndexOf("=");
+ if (i != -1) {
+ parts[0] = moduleName.substring(0, i) + '/';
+ parts[1] = moduleName.substring(i+1);
+ }
+ return parts;
+}
+
+
+//////////////////////////////////////////////////////////////////
+// Called directly from compiled code
+//
+function __pygwt_initHandlers(resize, beforeunload, unload) {
+ var oldOnResize = window.onresize;
+ window.onresize = function() {
+ resize();
+ if (oldOnResize)
+ oldOnResize();
+ };
+
+ var oldOnBeforeUnload = window.onbeforeunload;
+ window.onbeforeunload = function() {
+ var ret = beforeunload();
+
+ var oldRet;
+ if (oldOnBeforeUnload)
+ oldRet = oldOnBeforeUnload();
+