summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/strutils.nim63
-rw-r--r--lib/pure/unicode.nim1
-rw-r--r--lib/system/jssys.nim94
-rw-r--r--tests/testament/categories.nim3
-rw-r--r--web/news.txt2
5 files changed, 65 insertions, 98 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 6c561eaf9..aa29bb073 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -1344,8 +1344,8 @@ proc editDistance*(a, b: string): int {.noSideEffect,
 
 
 # floating point formating:
-
-proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
+when not defined(js):
+  proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
                                      importc: "sprintf", varargs, noSideEffect.}
 
 type
@@ -1370,29 +1370,44 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
   ## after the decimal point for Nim's ``biggestFloat`` type.
   ##
   ## If ``precision == 0``, it tries to format it nicely.
-  const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e']
-  var
-    frmtstr {.noinit.}: array[0..5, char]
-    buf {.noinit.}: array[0..2500, char]
-    L: cint
-  frmtstr[0] = '%'
-  if precision > 0:
-    frmtstr[1] = '#'
-    frmtstr[2] = '.'
-    frmtstr[3] = '*'
-    frmtstr[4] = floatFormatToChar[format]
-    frmtstr[5] = '\0'
-    L = c_sprintf(buf, frmtstr, precision, f)
+  when defined(js):
+    var res: cstring
+    case format
+    of ffDefault:
+      {.emit: "`res` = `f`.toString();".}
+    of ffDecimal:
+      {.emit: "`res` = `f`.toFixed(`precision`);".}
+    of ffScientific:
+      {.emit: "`res` = `f`.toExponential(`precision`);".}
+    result = $res
+    for i in 0 ..< result.len:
+      # Depending on the locale either dot or comma is produced,
+      # but nothing else is possible:
+      if result[i] in {'.', ','}: result[i] = decimalsep
   else:
-    frmtstr[1] = floatFormatToChar[format]
-    frmtstr[2] = '\0'
-    L = c_sprintf(buf, frmtstr, f)
-  result = newString(L)
-  for i in 0 ..< L:
-    # Depending on the locale either dot or comma is produced,
-    # but nothing else is possible:
-    if buf[i] in {'.', ','}: result[i] = decimalsep
-    else: result[i] = buf[i]
+    const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e']
+    var
+      frmtstr {.noinit.}: array[0..5, char]
+      buf {.noinit.}: array[0..2500, char]
+      L: cint
+    frmtstr[0] = '%'
+    if precision > 0:
+      frmtstr[1] = '#'
+      frmtstr[2] = '.'
+      frmtstr[3] = '*'
+      frmtstr[4] = floatFormatToChar[format]
+      frmtstr[5] = '\0'
+      L = c_sprintf(buf, frmtstr, precision, f)
+    else:
+      frmtstr[1] = floatFormatToChar[format]
+      frmtstr[2] = '\0'
+      L = c_sprintf(buf, frmtstr, f)
+    result = newString(L)
+    for i in 0 ..< L:
+      # Depending on the locale either dot or comma is produced,
+      # but nothing else is possible:
+      if buf[i] in {'.', ','}: result[i] = decimalsep
+      else: result[i] = buf[i]
 
 proc formatFloat*(f: float, format: FloatFormatMode = ffDefault,
                   precision: range[0..32] = 16; decimalSep = '.'): string {.
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index b059a7315..45f52eb7f 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -114,6 +114,7 @@ proc validateUtf8*(s: string): int =
     if ord(s[i]) <=% 127:
       inc(i)
     elif ord(s[i]) shr 5 == 0b110:
+      if ord(s[i]) < 0xc2: return i # Catch overlong ascii representations.
       if i+1 < L and ord(s[i+1]) shr 6 == 0b10: inc(i, 2)
       else: return i
     elif ord(s[i]) shr 4 == 0b1110:
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index 5bcddc5e6..54c6796c9 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -33,6 +33,9 @@ type
     lineNumber {.importc.}: int
     message {.importc.}: cstring
     stack {.importc.}: cstring
+
+  JSRef = ref RootObj # Fake type.
+
 {.deprecated: [TSafePoint: SafePoint, TCallFrame: CallFrame].}
 
 var
@@ -282,61 +285,6 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
     return true;
   """
 
-type
-  Document {.importc.} = object of RootObj
-    write: proc (text: cstring) {.nimcall.}
-    writeln: proc (text: cstring) {.nimcall.}
-    createAttribute: proc (identifier: cstring): ref Node {.nimcall.}
-    createElement: proc (identifier: cstring): ref Node {.nimcall.}
-    createTextNode: proc (identifier: cstring): ref Node {.nimcall.}
-    getElementById: proc (id: cstring): ref Node {.nimcall.}
-    getElementsByName: proc (name: cstring): seq[ref Node] {.nimcall.}
-    getElementsByTagName: proc (name: cstring): seq[ref Node] {.nimcall.}
-
-  NodeType* = enum
-    ElementNode = 1,
-    AttributeNode,
-    TextNode,
-    CDATANode,
-    EntityRefNode,
-    EntityNode,
-    ProcessingInstructionNode,
-    CommentNode,
-    DocumentNode,
-    DocumentTypeNode,
-    DocumentFragmentNode,
-    NotationNode
-  Node* {.importc.} = object of RootObj
-    attributes*: seq[ref Node]
-    childNodes*: seq[ref Node]
-    data*: cstring
-    firstChild*: ref Node
-    lastChild*: ref Node
-    nextSibling*: ref Node
-    nodeName*: cstring
-    nodeType*: NodeType
-    nodeValue*: cstring
-    parentNode*: ref Node
-    previousSibling*: ref Node
-    appendChild*: proc (child: ref Node) {.nimcall.}
-    appendData*: proc (data: cstring) {.nimcall.}
-    cloneNode*: proc (copyContent: bool) {.nimcall.}
-    deleteData*: proc (start, len: int) {.nimcall.}
-    getAttribute*: proc (attr: cstring): cstring {.nimcall.}
-    getAttributeNode*: proc (attr: cstring): ref Node {.nimcall.}
-    getElementsByTagName*: proc (): seq[ref Node] {.nimcall.}
-    hasChildNodes*: proc (): bool {.nimcall.}
-    insertBefore*: proc (newNode, before: ref Node) {.nimcall.}
-    insertData*: proc (position: int, data: cstring) {.nimcall.}
-    removeAttribute*: proc (attr: cstring) {.nimcall.}
-    removeAttributeNode*: proc (attr: ref Node) {.nimcall.}
-    removeChild*: proc (child: ref Node) {.nimcall.}
-    replaceChild*: proc (newNode, oldNode: ref Node) {.nimcall.}
-    replaceData*: proc (start, len: int, text: cstring) {.nimcall.}
-    setAttribute*: proc (name, value: cstring) {.nimcall.}
-    setAttributeNode*: proc (attr: ref Node) {.nimcall.}
-{.deprecated: [TNode: Node, TNodeType: NodeType, TDocument: Document].}
-
 when defined(kwin):
   proc rawEcho {.compilerproc, asmNoStackFrame.} =
     asm """
@@ -360,28 +308,28 @@ elif defined(nodejs):
     """
 
 else:
-  var
-    document {.importc, nodecl.}: ref Document
-
   proc ewriteln(x: cstring) =
-    var node = document.getElementsByTagName("body")[0]
-    if node != nil:
-      node.appendChild(document.createTextNode(x))
-      node.appendChild(document.createElement("br"))
-    else:
+    var node : JSRef
+    {.emit: "`node` = document.getElementsByTagName('body')[0];".}
+    if node.isNil:
       raise newException(ValueError, "<body> element does not exist yet!")
+    {.emit: """
+    `node`.appendChild(document.createTextNode(`x`));
+    `node`.appendChild(document.createElement("br"));
+    """.}
 
   proc rawEcho {.compilerproc.} =
-    var node = document.getElementsByTagName("body")[0]
-    if node == nil:
+    var node : JSRef
+    {.emit: "`node` = document.getElementsByTagName('body')[0];".}
+    if node.isNil:
       raise newException(IOError, "<body> element does not exist yet!")
-    asm """
-      for (var i = 0; i < arguments.length; ++i) {
-        var x = `toJSStr`(arguments[i]);
-        `node`.appendChild(document.createTextNode(x))
-      }
-    """
-    node.appendChild(document.createElement("br"))
+    {.emit: """
+    for (var i = 0; i < arguments.length; ++i) {
+      var x = `toJSStr`(arguments[i]);
+      `node`.appendChild(document.createTextNode(x));
+    }
+    `node`.appendChild(document.createElement("br"));
+    """.}
 
 # Arithmetic:
 proc addInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
@@ -532,8 +480,6 @@ proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b
 type NimString = string # hack for hti.nim
 include "system/hti"
 
-type JSRef = ref RootObj # Fake type.
-
 proc isFatPointer(ti: PNimType): bool =
   # This has to be consistent with the code generator!
   return ti.base.kind notin {tyObject,
diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim
index 762c92792..73d72289c 100644
--- a/tests/testament/categories.nim
+++ b/tests/testament/categories.nim
@@ -223,6 +223,9 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
                    "varres/tvartup"]:
     test "tests/" & testfile & ".nim"
 
+  for testfile in ["pure/strutils"]:
+    test "lib/" & testfile & ".nim"
+
 # ------------------------- manyloc -------------------------------------------
 #proc runSpecialTests(r: var TResults, options: string) =
 #  for t in ["lib/packages/docutils/highlite"]:
diff --git a/web/news.txt b/web/news.txt
index 192ddbb74..7765733a9 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -14,6 +14,8 @@ News
 
   - ``macros.newLit`` for ``bool`` now produces false/true symbols which
     actually work with the bool datatype.
+  - when compiling to JS, ``Node``, ``NodeType`` and ``Document`` are no longer
+    defined. Use the types defined in ``dom.nim`` instead.
 
 
 2015-10-27 Version 0.12.0 released