diff --git a/examples/js_dom_draw/draw.js.v b/examples/js_dom_draw/draw.js.v index 41d62aee88..efa88a1a1b 100644 --- a/examples/js_dom_draw/draw.js.v +++ b/examples/js_dom_draw/draw.js.v @@ -1,3 +1,4 @@ +/* import jsdom fn get_2dcontext(canvas jsdom.IElement) ?jsdom.CanvasRenderingContext2D { @@ -74,3 +75,8 @@ fn main() { context.clear_rect(0, 0, canv.width(), canv.height()) }) } +*/ + +fn main() { + panic('jsdom is being refactored; This example will be available soon') +} diff --git a/vlib/builtin/js/array.js.v b/vlib/builtin/js/array.js.v index cf006bdb22..8164e87059 100644 --- a/vlib/builtin/js/array.js.v +++ b/vlib/builtin/js/array.js.v @@ -397,3 +397,11 @@ pub fn (a []string) str() string { res := sb.str() return res } + +pub fn (a array) to_js_array() JS.Array { + tmp := JS.Array.prototype.constructor() + for i in 0 .. a.len { + tmp.push(a.arr.get(i)) + } + return tmp +} diff --git a/vlib/builtin/js/jsfns.js.v b/vlib/builtin/js/jsfns.js.v index bc1e0ece5e..5f9254c910 100644 --- a/vlib/builtin/js/jsfns.js.v +++ b/vlib/builtin/js/jsfns.js.v @@ -9,14 +9,17 @@ module builtin pub interface JS.Object {} +[single_impl] pub interface JS.BigInt { JS.Any } +[single_impl] pub interface JS.Number { JS.Any } +[single_impl] pub interface JS.String { JS.Any length JS.Number @@ -34,8 +37,10 @@ pub interface JS.String { lastIndexOf(needle JS.String) JS.Number } +[single_impl] pub interface JS.Boolean { JS.Any + length JS.Number } pub interface JS.Map { diff --git a/vlib/builtin/js/string.js.v b/vlib/builtin/js/string.js.v index 65ac080267..61072eab21 100644 --- a/vlib/builtin/js/string.js.v +++ b/vlib/builtin/js/string.js.v @@ -17,7 +17,7 @@ pub fn (s string) runes() []rune { } pub fn (s string) slice(a int, b int) string { - return string(s.str.slice(a, b)) + return string(s.str.slice(JS.Number(a), JS.Number(b))) } pub fn (s string) substr(start int, end int) string { @@ -88,7 +88,7 @@ pub fn (s string) split(dot string) []string { pub fn (s string) bytes() []byte { sep := '' tmparr := s.str.split(sep.str).map(fn (it JS.Any) JS.Any { - return JS.Any(byte(JS.String(it).charCodeAt(0))) + return JS.Any(byte(JS.String(it).charCodeAt(JS.Number(0)))) }) _ := tmparr mut arr := []byte{} @@ -98,8 +98,8 @@ pub fn (s string) bytes() []byte { } pub fn (s string) capitalize() string { - part := string(s.str.slice(1, int(s.str.length))) - return string(s.str.charAt(0).toUpperCase().concat(part.str)) + part := string(s.str.slice(JS.Number(1), s.str.length)) + return string(s.str.charAt(JS.Number(0)).toUpperCase().concat(part.str)) } pub fn (s string) clone() string { diff --git a/vlib/jsdom/context.v b/vlib/jsdom/context.v deleted file mode 100644 index af40fc38f1..0000000000 --- a/vlib/jsdom/context.v +++ /dev/null @@ -1,34 +0,0 @@ -// Wrapper around 2d context and WebGL APIs - -module jsdom - -pub struct ContextAttributes { -pub: - alpha bool - desynchronized bool -} - -pub enum PowerPreference { - default_ - high_performance - low_performance -} - -pub struct WebGLAttributes { -pub: - alpha bool - desynchronized bool - antialias bool - depth bool - fail_if_major_perf_caveat bool - power_preference PowerPreference - premultiplied_alpha bool - preserve_drawing_buffer bool - stencil bool -} - -pub struct NoneContext {} - -pub type ContextResult = CanvasRenderingContext2D | NoneContext | WebGLRenderingContext - -pub struct JS.CanvasGradient {} diff --git a/vlib/jsdom/context_2d.js.v b/vlib/jsdom/context_2d.js.v deleted file mode 100644 index d48070dd54..0000000000 --- a/vlib/jsdom/context_2d.js.v +++ /dev/null @@ -1,409 +0,0 @@ -module jsdom - -struct JS.CanvasRenderingContext2D { -mut: - lineWidth JS.Number - lineCap JS.String - lineJoin JS.String - miterLimit JS.Number - lineDashOffset JS.Number - font JS.String - textAlign JS.String - textBaseline JS.String - direction JS.String - fillStyle voidptr - strokeStyle voidptr - shadowBlur JS.Number - shadowColor JS.String - shadowOffsetX JS.Number - shadowOffsetY JS.Number - globalAlpha JS.Number - globalCompositeOperation JS.String -} - -pub enum LineJoin { - bevel - round - miter -} - -pub enum TextAlign { - left - right - center - start - end -} - -pub struct CanvasRenderingContext2D { -mut: - ctx JS.CanvasRenderingContext2D [noinit] -} - -pub type StrokeStyle = JS.CanvasGradient | string - -pub fn (ctx CanvasRenderingContext2D) begin_path() { - #ctx.ctx.beginPath(); -} - -pub fn (ctx CanvasRenderingContext2D) set_line_dash(arr []f64) { - #let tmp = [] - - for x in arr { - #tmp.push(x.val); - - _ := x - } - #ctx.ctx.setLineDash(tmp); -} - -pub fn (ctx CanvasRenderingContext2D) get_line_dash() []f64 { - arr := []f64{} - #for (elem of ctx.ctx.getLineDash()) { array_push(arr,elem); } - - return arr -} - -pub fn (ctx CanvasRenderingContext2D) set_text_align(align TextAlign) { - match align { - .left { - #ctx.ctx.textAlign = 'start'; - } - .right { - #ctx.ctx.textAlign = 'right'; - } - .center { - #ctx.ctx.textAlign = 'center'; - } - .start { - #ctx.ctx.textAlign = 'start'; - } - .end { - #ctx.ctx.textAlign = 'end'; - } - } -} - -pub fn (ctx CanvasRenderingContext2D) set_line_join(j LineJoin) { - match j { - .bevel { - #ctx.ctx.lineJoin = 'bevel' - } - .round { - #ctx.ctx.lineJoin = 'round' - } - .miter { - #ctx.ctx.lineJoin = 'miter' - } - } -} - -pub fn (ctx CanvasRenderingContext2D) set_stroke_style(style StrokeStyle) { - #ctx.ctx.strokeStyle = style instanceof string ? style.str : style -} - -pub fn (ctx CanvasRenderingContext2D) set_fill_style(style StrokeStyle) { - #ctx.ctx.fillStyle = style instanceof string ? style.str : style -} - -pub fn (ctx CanvasRenderingContext2D) line_width() f64 { - res := 0 - #res.val = ctx.ctx.lineWidth - - return res -} - -pub fn (ctx CanvasRenderingContext2D) font() string { - res := '' - #res.str = ctx.ctx.font; - - return res -} - -pub fn (ctx CanvasRenderingContext2D) set_font(font string) { - #ctx.ctx.font = font.str; -} - -pub fn (ctx CanvasRenderingContext2D) fill_rect(x f64, y f64, width f64, height f64) { - #ctx.ctx.fillRect(x.val,y.val,width.val,height.val) -} - -pub fn (ctx CanvasRenderingContext2D) set_line_width(width f64) { - #ctx.ctx.lineWidth = width.val -} - -pub fn (ctx CanvasRenderingContext2D) move_to(x f64, y f64) { - #ctx.ctx.moveTo(x.val,y.val); -} - -pub fn (ctx CanvasRenderingContext2D) line_to(x f64, y f64) { - #ctx.ctx.lineTo(x.val,y.val); -} - -pub fn (ctx CanvasRenderingContext2D) stroke() { - #ctx.ctx.stroke(); -} - -pub fn (ctx CanvasRenderingContext2D) close_path() { - #ctx.ctx.closePath(); -} - -pub fn (ctx CanvasRenderingContext2D) stroke_rect(x f64, y f64, width f64, height f64) { - #ctx.ctx.strokeRect(x.val,y.val,width.val,height.val); -} - -pub fn (ctx CanvasRenderingContext2D) clear_rect(x f64, y f64, width f64, height f64) { - #ctx.ctx.clearRect(x.val,y.val,width.val,height.val); -} - -pub fn (ctx CanvasRenderingContext2D) create_linear_gradient(x0 f64, y0 f64, x1 f64, y1 f64) JS.CanvasGradient { - return ctx.ctx.createLinearGradient(x0, y0, x1, y1) -} - -pub fn (ctx CanvasRenderingContext2D) create_conic_gradient(start_angle f64, x f64, y f64) JS.CanvasGradient { - return ctx.ctx.createConicGradient(start_angle, x, y) -} - -pub fn (ctx CanvasRenderingContext2D) create_radial_gradient(x0 f64, y0 f64, r0 f64, x1 f64, y1 f64, r1 f64) JS.CanvasGradient { - return ctx.ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) -} - -pub fn (ctx CanvasRenderingContext2D) bezier_curve_to(cp1x f64, cp1y f64, cp2x f64, cp2y f64, x f64, y f64) { - #ctx.ctx.bezierCurveTo(cp1x.val,cp1y.val,cp2x.val,cp2y.val, x.val,y.val); -} - -pub fn (ctx CanvasRenderingContext2D) quadratic_curve_to(cpx f64, cpy f64, x f64, y f64) { - #ctx.ctx.quadraticCurveTo(cpx.val,cpy.val,x.val,y.val); -} - -pub fn (ctx CanvasRenderingContext2D) arc(x f64, y f64, radius f64, start_angle f64, end_angle f64, counter_clockwise bool) { - #ctx.ctx.arc(x.val,y.val,radius.val,start_angle.val,end_angle.val,counter_clockwise.val) -} - -pub fn (ctx CanvasRenderingContext2D) arc_to(x1 f64, y1 f64, x2 f64, y2 f64, radius f64) { - #ctx.ctx.arcTo(x1.val,y1.val,x2.val,y2.val,radius.val); -} - -pub fn (ctx CanvasRenderingContext2D) ellipse(x f64, y f64, radius_x f64, radius_y f64, rotation f64, start_angle f64, end_angle f64, counter_clockwise bool) { - #ctx.ctx.ellipse(x.val,y.val,radius_x.val,radius_y.val,rotation.val,start_angle.val,end_angle.val,counter_clockwise.val); -} - -pub fn (ctx CanvasRenderingContext2D) rect(x f64, y f64, width f64, height f64) { - #ctx.ctx.rect(x.val,y.val,widht.val,height.val); -} - -pub fn (ctx CanvasRenderingContext2D) draw_focus_if_needed(el IElement) { - #ctx.ctx.drawFocusIfNeeded(el.val.node); -} - -pub fn (ctx CanvasRenderingContext2D) draw_focus_if_needed_wpath(path Path2D, el IElement) { - #ctx.ctx.drawFocusIfNeeded(path.path, el.val.node); -} - -fn (ctx JS.CanvasRenderingContext2D) createRadialGradient(x0 f64, y0 f64, r0 f64, x1 f64, y1 f64, r1 f64) JS.CanvasGradient - -fn (ctx JS.CanvasRenderingContext2D) createConicGradient(startAngle f64, x f64, y f64) JS.CanvasGradient - -fn (ctx JS.CanvasRenderingContext2D) createLinearGradient(x0 f64, y0 f64, x1 f64, y1 f64) JS.CanvasGradient - -pub fn (gradient JS.CanvasGradient) addColorStop(x f64, color string) - -/// fill_text draws a text string at the specified coordinates. `max_width` allows specifying a maximum -/// width for the rendered text, set max_width to -1.0 to automatically adjust text width. -pub fn (ctx CanvasRenderingContext2D) fill_text(text string, x f64, y f64, max_width f64) { - if max_width == -1.0 { - #ctx.ctx.fillText(text.str,x.val,y.val,max_width.val) - } else { - #ctx.ctx.fillText(text.str,x.val,y.val) - } -} - -/// stoke_text strokes — that is, draws the outlines of — the characters of a text string at the specified coordinates. -/// `max_width` allows specifying a maximum width for the rendered text, set max_width to -1.0 to automatically adjust text width. -pub fn (ctx CanvasRenderingContext2D) stroke_text(text string, x f64, y f64, max_width f64) { - if max_width == -1.0 { - #ctx.ctx.stokeText(text.str,x.val,y.val,max_width.val) - } else { - #ctx.ctx.stokeText(text.str,x.val,y.val) - } -} - -pub fn (ctx CanvasRenderingContext2D) measure_text(text string) TextMetrics { - metrics := TextMetrics{} - #let tmp = ctx.ctx.measureText(text.str); - #metrics.width = new f64(tmp.width); - #metrics.actual_bounding_box_left = new f64(tmp.actualBoundingBoxLeft); - #metrics.actual_bounding_box_right = new f64(tmp.actualBoundingBoxRight); - #metrics.actual_bounding_box_ascent = new f64(tmp.actualBoundingBoxAscent); - #metrics.actual_bounding_box_descent = new f64(tmp.actualBoundingBoxDescent); - #metrics.font_bounding_box_ascent = new f64(tmp.fontBoundingBoxAscent); - #metrics.font_bounding_box_descent = new f64(tmp.fontBoundingBoxDescent); - #metrics.em_height_ascent = new f64(tmp.emHeightAscent); - #metrics.em_height_descent = new f64(tmp.emHeightDescent); - #metrics.hanging_baseline = new f64(tmp.hangingBaseline); - #metrics.alphabetic_baseline = new f64(tmp.alphabeticBaseline); - #metrics.ideographic_baseline = new f64(tmp.ideographicBaseline); - - return metrics -} - -pub fn (ctx CanvasRenderingContext2D) fill_path(p Path2D) { - #ctx.ctx.fill(p.path); -} - -pub enum FillRule { - nonzero - evenodd -} - -pub fn (ctx CanvasRenderingContext2D) clip_rule(rule FillRule) { - match rule { - .nonzero { - #ctx.ctx.clip('nonzero') - } - .evenodd { - #ctx.ctx.clip('evenodd') - } - } -} - -pub fn (ctx CanvasRenderingContext2D) clip() { - #ctx.ctx.clip(); -} - -pub fn (ctx CanvasRenderingContext2D) clip_path(path Path2D) { - #ctx.ctx.clip(path.path); -} - -pub fn (ctx CanvasRenderingContext2D) clip_path_rule(path Path2D, rule FillRule) { - match rule { - .nonzero { - #ctx.ctx.clip(path.path, 'nonzero') - } - .evenodd { - #ctx.ctx.clip(path.path,'evenodd') - } - } -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_path(x f64, y f64) bool { - res := false - #res.val = ctx.ctx.isPointInPath(x.val,y.val); - - return res -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_path_2(path Path2D, x f64, y f64) bool { - res := false - #res.val = ctx.ctx.isPointInPath(path.path,x.val,y.val); - - return res -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_path_3(path Path2D, x f64, y f64, rule FillRule) bool { - res := false - match rule { - .nonzero { - #res.val = ctx.ctx.isPointInPath(path.path,x.val,y.val,'nonzero'); - } - .evenodd { - #res.val = ctx.ctx.isPointInPath(path.path,x.val,y.val,'evenadd'); - } - } - return res -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_path_4(x f64, y f64, rule FillRule) bool { - res := false - match rule { - .nonzero { - #res.val = ctx.ctx.isPointInPath(x.val,y.val,'nonzero'); - } - .evenodd { - #res.val = ctx.ctx.isPointInPath(x.val,y.val,'evenadd'); - } - } - return res -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_stroke(x f64, y f64) bool { - res := false - #res.val = ctx.ctx.isPointInStroke(x.val,y.val); - - return res -} - -pub fn (ctx CanvasRenderingContext2D) is_point_in_stroke_path(path Path2D, x f64, y f64) bool { - res := false - #res.val = ctx.ctx.isPointInStroke(path.path, x.val,y.val); - - return res -} - -pub fn (ctx CanvasRenderingContext2D) get_transform() DOMMatrix { - m := DOMMatrix{} - #m.matrix = ctx.ctx.getTransform(); - - return m -} - -pub fn (ctx CanvasRenderingContext2D) rotate(angle f64) { - #ctx.ctx.rotate(angle.val); -} - -pub fn (ctx CanvasRenderingContext2D) scale(x f64, y f64) { - #ctx.ctx.scale(x.val,y.val); -} - -pub fn (ctx CanvasRenderingContext2D) translate(x f64, y f64) { - #ctx.ctx.translate(x.val,y.val) -} - -pub fn (ctx CanvasRenderingContext2D) transform(a f64, b f64, c f64, d f64, e f64, f f64) { - #ctx.ctx.transform(a.val,b.val,c.val,d.val,e.val,f.val); -} - -pub fn (ctx CanvasRenderingContext2D) set_transform_matrix(m DOMMatrix) { - #ctx.ctx.setTransform(m.matrix); -} - -pub fn (ctx CanvasRenderingContext2D) set_transform(a f64, b f64, c f64, d f64, e f64, f f64) { - #ctx.ctx.setTransform(a.val,b.val,c.val,d.val,e.val,f.val); -} - -pub fn (ctx CanvasRenderingContext2D) global_alpha() f64 { - res := 0.0 - #res.val = ctx.ctx.globalAlpha - - return res -} - -pub fn (ctx CanvasRenderingContext2D) set_global_alpha(alpha f64) { - #ctx.ctx.globalAlpha = alpha.val; -} - -pub fn (ctx CanvasRenderingContext2D) global_composite_operation() string { - res := '' - #res.str = ctx.ctx.globalCompositeOperation - - return res -} - -pub fn (ctx CanvasRenderingContext2D) set_global_composite_operation(typ string) { - #ctx.ctx.globalCompositeOperation = typ.str; -} - -pub fn (ctx CanvasRenderingContext2D) save() { - #ctx.ctx.save(); -} - -pub fn (ctx CanvasRenderingContext2D) restore() { - #ctx.ctx.restore() -} - -pub fn (ctx CanvasRenderingContext2D) canvas() HTMLCanvasElement { - elem := HTMLCanvasElement{} - #elem.node = ctx.ctx.canvas() - - return elem -} diff --git a/vlib/jsdom/document.js.v b/vlib/jsdom/document.js.v deleted file mode 100644 index d65e24c3a8..0000000000 --- a/vlib/jsdom/document.js.v +++ /dev/null @@ -1,230 +0,0 @@ -module jsdom - -pub struct JS.Document { -} - -pub struct Document { - Node -} - -pub struct Location { -mut: - loc JS.Location [noinit] -} - -pub fn (l Location) str() string { - mut res := 'Location{\n' - res += ' origin: $l.origin()\n' - res += ' href: $l.href()\n' - res += ' protocol: $l.protocol()\n' - res += ' host: $l.host()\n' - res += ' hostname: $l.hostname()\n' - res += ' port: $l.port()\n' - res += ' pathname: $l.pathname()\n' - res += ' search: $l.search()\n' - res += ' hash: $l.hash()\n' - return res -} - -pub fn (mut l Location) assign(url string) { - #l.val.loc.assign(url.str) -} - -pub fn (l Location) reload() { - #l.loc.reload() -} - -pub fn (mut l Location) replace(url string) { - #l.val.loc.replace(url.str) -} - -pub fn (l Location) origin() string { - return tos(l.loc.origin) -} - -pub fn (l Location) href() string { - return tos(l.loc.href) -} - -pub fn (mut l Location) set_href(href string) { - l.loc.href = href.str -} - -pub fn (l Location) protocol() string { - return tos(l.loc.protocol) -} - -pub fn (mut l Location) set_protocol(protocol string) { - l.loc.protocol = protocol.str -} - -pub fn (l Location) host() string { - return tos(l.loc.host) -} - -pub fn (mut l Location) set_host(host string) { - l.loc.host = host.str -} - -pub fn (l Location) hostname() string { - return tos(l.loc.hostname) -} - -pub fn (mut l Location) set_hostname(hostname string) { - l.loc.hostname = hostname.str -} - -pub fn (l Location) port() string { - return tos(l.loc.port) -} - -pub fn (mut l Location) set_port(port string) { - l.loc.port = port.str -} - -pub fn (l Location) pathname() string { - return tos(l.loc.pathname) -} - -pub fn (mut l Location) set_pathname(pathname string) { - l.loc.pathname = pathname.str -} - -pub fn (l Location) hash() string { - return tos(l.loc.hash) -} - -pub fn (mut l Location) set_hash(hash string) { - l.loc.hash = hash.str -} - -pub fn (l Location) search() string { - return tos(l.loc.search) -} - -pub fn (mut l Location) set_search(search string) { - l.loc.search = search.str -} - -pub struct JS.Location { -pub: - origin JS.String -mut: - href JS.String - protocol JS.String - host JS.String - hostname JS.String - port JS.String - pathname JS.String - search JS.String - hash JS.String -} - -pub fn (doc Document) active_element() Element { - mut elem := Element{} - #elem.node = doc.node.activeElement; - - return elem -} - -pub fn (doc Document) get(name string) ?Element { - mut elem := Element{} - #elem.node = doc.node[name.str]; - #console.log(elem.node) - #if (elem.node === null || elem.node === undefined) return new $ref(new Option({state: new byte(2),err: none__})); - - return elem -} - -// location returns URI of the document -pub fn (doc Document) location() Location { - mut loc := Location{} - #loc.loc = doc.node.location; - - return loc -} - -// get_title returns current title of document -pub fn (doc Document) get_title() string { - res := '' - #res.str = doc.node.title; - - return res -} - -// set_title updates document title -pub fn (doc Document) set_title(title string) { - #doc.node.title = title.str; -} - -// url returns document location as a string -pub fn (doc Document) url() string { - res := '' - #res.str = doc.node.URL; - - return res -} - -// node casts `Document` back to `Node`. -pub fn (doc Document) node() Node { - node := Node{} - #node.node = doc.node - - return node -} - -pub fn (doc Document) get_element_by_id(id string) ?IElement { - mut elem := IElement(Element{}) - found := false - #let tmp = doc.node.getElementById(id.str); - #elem = jsdom__dispatch_event_target(tmp); - #found.val = !(elem.node == null) - if !found { - return none - } - return elem -} - -pub type DocumentPrepend = Node | string - -pub fn (doc Document) prepend(nodes_or_strings ...DocumentPrepend) ? { - caught := false - err := '' - #try { - - for elem in nodes_or_strings { - match elem { - string { - #doc.node.prepend(elem.str) - } - Node { - #doc.node.prepend(elem.node) - } - } - } - #} catch (e) { caught.val = true; err.str = e.toString(); } - if caught { - return error(err) - } -} - -pub fn (doc Document) create_element(tag_name string) Element { - elem := Element{} - #elem.node = doc.node.createElement(tag_name.str) - - return elem -} - -pub fn get_document() Document { - doc := Document{} - #doc.node = document; - - return doc -} - -pub fn (elem Document) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} diff --git a/vlib/jsdom/dom.js.v b/vlib/jsdom/dom.js.v deleted file mode 100644 index 24c8287590..0000000000 --- a/vlib/jsdom/dom.js.v +++ /dev/null @@ -1,202 +0,0 @@ -// DOM API for JS backend -module jsdom - -[heap] -pub struct JS.Node { - baseURI JS.String [noinit] - childNodes JS.NodeList [noinit] - firstChild voidptr [noinit] - isConnected JS.bool [noinit] - lastChild voidptr [noinit] - nextSibling voidptr [noinit] - nodeName JS.String [noinit] - nodeType NodeType [noinit] - nodeValue voidptr [noinit] - ownerDocument JS.Document [noinit] - parentNode voidptr [noinit] - parentElement JS.Element [noinit] - previousSibling voidptr [noinit] - textContext voidptr -} - -pub struct JS.NodeList { -pub mut: - length JS.Number -} - -pub enum NodeType { - element = 1 - attribute = 2 - text = 3 - cdata_section = 4 - entity_reference = 5 - entity = 6 - processing_instruction = 7 - comment = 8 - document = 9 - document_type = 10 - document_fragment = 11 - notation = 12 -} - -pub struct Node { - node JS.Node [noinit] -} - -pub fn (n Node) typ() NodeType { - return n.node.nodeType -} - -/// IEventTarget interface is implemented by objects that can receive events and may have listeners for them. -// In other words, any target of events implements the three methods associated with this interface. -// TODO: remove_event_listener and dispatch_event -pub interface IEventTarget { - add_event_listener(event string, cb EventCallback) -} - -/// The DOM Node interface is an abstract base class upon which many other DOM API objects are based, thus -// letting those object types to be used similarly and often interchangeably. As an abstract class, -// there is no such thing as a plain Node object. All objects that implement Node functionality are based on one of its subclasses. -// Most notable are Document, Element, and DocumentFragment. -pub interface INode { - IEventTarget - typ() NodeType -} - -pub fn (elem Node) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} - -pub fn (n INode) is_(ty NodeType) bool { - res := false - #res.val = n.node.nodeType == ty - - return res -} - -pub fn (n INode) document() ?Document { - res := Document{} - if n.is_(.document) { - #res.node = n.node - - return res - } else { - return none - } -} - -pub fn (n INode) element() ?Element { - res := Element{} - if n.is_(.element) { - #res.node = n.node - - return res - } else { - return none - } -} - -pub fn (n INode) append_child(child INode) { - #n.node.appendChild(child.node) -} - -pub fn (n INode) clone_node(deep ...int) INode { - cloned := Node{} - if deep.len == 0 { - #cloned.node = n.node.cloneNode() - } else { - #cloned.node = n.node.cloneNode(deep.arr.get(new int(0)).val) - } - return cloned -} - -pub fn (n INode) contains(other INode) bool { - res := false - #res.val = n.node.contains(other.node) - - return res -} - -pub fn (n INode) get_root_node() INode { - root := Node{} - #root.node = n.node.getRootNode() - - return root -} - -pub fn (n INode) has_child_nodes() bool { - res := false - #res.val = n.node.hasChildNodes() - - return res -} - -pub fn (n INode) insert_before(new_node INode, reference_node INode) Node { - inserted := Node{} - #inserted.node = n.node.insertBefore(new_node.node,reference_node.node) - - return inserted -} - -/* -pub fn (x Node) == (y Node) bool { - res := false - #res.val = x.node.isEqualNode(y.node) - - return res -}*/ - -pub fn (n INode) remove_child(child INode) { - #n.node.removeChild(child.node) -} - -pub fn (n INode) replace_child(new_child INode, old_child INode) INode { - #old_child.node = n.node.replace_child(new_child.node,old_child.node) - - return old_child -} - -pub struct JS.EventTarget {} - -fn dispatch_event_target(target JS.EventTarget) IEventTarget { - mut ret := IEventTarget(Element{}) - #if (target instanceof HTMLCanvasElement) { ret = new jsdom__HTMLCanvasElement({}); ret.node = target; } - #else if (target instanceof HTMLElement) { ret = new jsdom__HTMLElement({}); ret.node = target; } - #else if (target instanceof Window) { ret = new jsdom__Window({}); ret.node = target;} - #else if (target instanceof SVGElement) { ret = new jsdom__SVGElement({}); ret.node = target; } - #else if (target instanceof Element) { ret = new jsdom__Element({}); ret.node = target; } - #else if (target instanceof Document) { ret = new jsdom__Document({}); ret.node = target; } - - return ret -} - -pub type EventCallback = fn (_ IEventTarget, _ IEvent) - -pub const ( - document = Document{} - window = Window{} -) - -fn init() { - #jsdom__document.node = document; - #jsdom__window.node = window; -} - -pub struct TextMetrics { -pub: - width f64 - actual_bounding_box_left f64 - actual_bounding_box_right f64 - font_bounding_box_ascent f64 - font_bounding_box_descent f64 - actual_bounding_box_ascent f64 - actual_bounding_box_descent f64 - em_height_ascent f64 - em_height_descent f64 - hanging_baseline f64 - alphabetic_baseline f64 - ideographic_baseline f64 -} diff --git a/vlib/jsdom/dom.v b/vlib/jsdom/dom.v deleted file mode 100644 index 5d5139ebad..0000000000 --- a/vlib/jsdom/dom.v +++ /dev/null @@ -1,10 +0,0 @@ -// DOM API wrapper for JS backend -module jsdom - -pub fn get_html_canvas_element(elem IElement) ?HTMLCanvasElement { - if elem is HTMLCanvasElement { - return *elem - } else { - return none - } -} diff --git a/vlib/jsdom/dom_token_list.js.v b/vlib/jsdom/dom_token_list.js.v deleted file mode 100644 index 37876fddf6..0000000000 --- a/vlib/jsdom/dom_token_list.js.v +++ /dev/null @@ -1,97 +0,0 @@ -module jsdom - -pub struct JS.DOMString { -} - -pub struct JS.DOMTokenList { - length JS.Number - value JS.DOMString -} - -pub struct DOMTokenList { - list JS.DOMTokenList [noinit] -} - -pub fn (x DOMTokenList) len() int { - res := 0 - #res.val = x.list.length; - - return res -} - -pub fn (x DOMTokenList) item(idx int) ?string { - res := '' - #let tmp = x.list.item(idx.list.val) - #if (tmp === undefined) return new Option({state: new byte(2),err: none__}); - #res.val = tmp - - return res -} - -pub fn (x DOMTokenList) contains(token string) bool { - res := false - #res.val = x.list.contains(token.str); - - return res -} - -pub fn (x DOMTokenList) add(tokens ...string) { - for token in tokens { - #x.list.add(token.str); - - _ := token - } -} - -pub fn (x DOMTokenList) remove(tokens ...string) { - for token in tokens { - #x.list.remove(token.str); - - _ := token - } -} - -pub fn (x DOMTokenList) replace(old_token string, new_token string) bool { - is_replaced := false - #is_replaced.val = x.list.replace(old_token.str,new_token.str); - - return is_replaced -} - -// supports returns true if the given `token` is in the associated attibute's supported tokens. -pub fn (x DOMTokenList) supports(token string) bool { - supports := false - #supports.val = x.list.supports(token.str) - - return supports -} - -// toggle removes a given token from the list and returns `false`. If token does not exist -// it is added and function returns `true`. -pub fn (x DOMTokenList) toggle(token string, force bool) bool { - res := false - #res.val = x.list.toggle(token.str, force.val); - - return res -} - -// entries returns array of all tokens in this token list -pub fn (x DOMTokenList) values() []string { - mut res := []string{} - #for (let [_,value] of x.list.entries()) array_push(res, new string(value)); - - return res -} - -pub fn (x DOMTokenList) str() string { - mut fmt := 'DOMTokenList[' - values := x.values() - for i, val in values { - fmt += '"' + val + '"' - if i != values.len - 1 { - fmt += ',' - } - } - fmt += ']' - return fmt -} diff --git a/vlib/jsdom/element.js.v b/vlib/jsdom/element.js.v deleted file mode 100644 index 74f0aa69bf..0000000000 --- a/vlib/jsdom/element.js.v +++ /dev/null @@ -1,93 +0,0 @@ -module jsdom - -pub struct JS.Element { - classList JS.DOMTokenList - childElementCount JS.Number - className JS.String - clientHeight JS.Number - clientWidth JS.Number - clientTop JS.Number - clientLeft JS.Number - id JS.String - innerHTML JS.String - namespaceURI JS.String - outerHTML JS.String - scrollHeight JS.Number - scrollLeft JS.Number - scrollTop JS.Number - scrollWidth JS.Number -} - -pub struct Element { - Node -} - -pub fn (e Element) str() string { - res := '' - #res.str = e.node + '' - - return res -} - -pub fn (elem Element) typ() NodeType { - return .element -} - -pub fn (e Element) class_name() string { - res := '' - #res.str = e.node.className - - return res -} - -pub fn (e Element) class_list() DOMTokenList { - list := DOMTokenList{} - #list.list = e.node.classList - - return list -} - -// node casts `Element` back to `Node`. -pub fn (elem Element) node() Node { - node := Node{} - #node.node = elem.node - - return node -} - -pub fn (elem Element) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} - -pub interface IElement { - INode -} - -pub struct HTMLElement { - Element -} - -pub fn (elem HTMLElement) typ() NodeType { - return .element -} - -pub fn (elem HTMLElement) access_key() string { - res := '' - #res.str = elem.node.accessKey; - - return res -} - -pub fn (mut elem HTMLElement) set_access_key(key string) { - #elem.val.node.accessKey = key.str; -} - -pub fn (elem HTMLElement) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} diff --git a/vlib/jsdom/events.js.v b/vlib/jsdom/events.js.v deleted file mode 100644 index 2f4b3251fd..0000000000 --- a/vlib/jsdom/events.js.v +++ /dev/null @@ -1,164 +0,0 @@ -module jsdom - -pub interface IEvent { - composed_path() []IEventTarget -} - -pub struct JS.Event {} - -pub struct JS.MouseEvent {} - -pub struct Event { - event JS.Event [noinit] -} - -pub fn (ev Event) composed_path() []IEventTarget { - mut composed := []IEventTarget{} - #ev.event.composedPath().forEach((item) => { - #array_push(composed, jsdom__dispatch_event()) - #}) - - return composed -} - -pub struct UIEvent { - Event -} - -// detail returns `int` with detail about the event, depending on the event type. -pub fn (ev UIEvent) detail() int { - ret := 0 - #ret.val = ev.event.detail - - return ret -} - -pub struct MouseEvent { - UIEvent -} - -// button returns the button number that was pressed (if applicable) when the mouse event was fired. -pub fn (ev MouseEvent) button() int { - ret := 0 - #ret.val = ev.event.button; - - return ret -} - -// alt_key returns `true` if the `alt` key was down when the mouse event was fired. -pub fn (ev MouseEvent) alt_key() bool { - ret := false - #ret.val = ev.event.altKey; - - return ret -} - -// buttons returns the buttons being depressed (if any) when the mouse event was fired. -pub fn (ev MouseEvent) buttons() int { - ret := 0 - #ret.val = ev.event.buttons; - - return ret -} - -// client_x returns the X coordinate of the mouse pointer in local coordinates. -pub fn (ev MouseEvent) client_x() int { - ret := 0 - #ret.val = ev.event.clientX; - - return ret -} - -// client_y returns the Y coordinate of the mouse pointer in local coordinates. -pub fn (ev MouseEvent) client_y() int { - ret := 0 - #ret.val = ev.event.clientY; - - return ret -} - -// ctrl_key returns `true` if the `ctrl` key was down when the mouse event was fired. -pub fn (ev MouseEvent) ctrl_key() bool { - ret := false - #ret.val = ev.event.ctrlKey; - - return ret -} - -// meta_key returns `true` if the `meta` key was down when the mouse event was fired. -pub fn (ev MouseEvent) meta_key() bool { - ret := false - #ret.val = ev.event.metaKey; - - return ret -} - -// movenet_x reaturns the X coordinate of the mouse pointer relative to the position of the last `mousemove` event. -pub fn (ev MouseEvent) movement_x() int { - ret := 0 - #ret.val = ev.event.movementX; - - return ret -} - -// movenet_y reaturns the Y coordinate of the mouse pointer relative to the position of the last `mousemove` event. -pub fn (ev MouseEvent) movement_y() int { - ret := 0 - #ret.val = ev.event.movementY; - - return ret -} - -// offset_x returns the X coordinate of the mouse pointer relative to the position of the padding edge of the target node. -pub fn (ev MouseEvent) offset_x() int { - ret := 0 - #ret.val = ev.event.offsetX; - - return ret -} - -// offset_y reaturns the Y coordinate of the mouse pointer relative to the position of the padding edge of the target node. -pub fn (ev MouseEvent) offset_y() int { - ret := 0 - #ret.val = ev.event.offsetY; - - return ret -} - -pub fn (ev MouseEvent) composed_path() []IEventTarget { - mut composed := []IEventTarget{} - #ev.event.composedPath().forEach((item) => { - #array_push(composed, jsdom__dispatch_event()) - #}) - - return composed -} - -pub struct AbortSignal { - Event -} - -pub fn (ev AbortSignal) composed_path() []IEventTarget { - mut composed := []IEventTarget{} - #ev.event.composedPath().forEach((item) => { - #array_push(composed, jsdom__dispatch_event(item)) - #}) - - return composed -} - -pub fn (sig AbortSignal) aborted() bool { - res := false - #res.val = sig.event.aborted; - - return res -} - -fn dispatch_event(event JS.Event) IEvent { - mut ret := IEvent(Event{}) - #if (event instanceof AbortSignal) { ret = new jsdom__AbortSignal({}); } - #else if (event instanceof MouseEvent) { ret = new jsdom__MouseEvent({}); } - #ret.event = event - - return ret -} diff --git a/vlib/jsdom/html_canvas_element.js.v b/vlib/jsdom/html_canvas_element.js.v deleted file mode 100644 index 06079dc913..0000000000 --- a/vlib/jsdom/html_canvas_element.js.v +++ /dev/null @@ -1,47 +0,0 @@ -module jsdom - -pub struct HTMLCanvasElement { - HTMLElement -} - -pub fn (cv HTMLCanvasElement) height() int { - ret := 0 - #ret.val = cv.node.height; - - return ret -} - -pub fn (cv HTMLCanvasElement) width() int { - ret := 0 - #ret.val = cv.node.width; - - return ret -} - -pub fn (cv HTMLCanvasElement) typ() NodeType { - return .element -} - -pub fn (elem HTMLCanvasElement) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} - -pub fn (elem HTMLCanvasElement) get_context(ctx_ string) ContextResult { - mut res := NoneContext{} - #let ctx = elem.node.getContext(ctx_.str); - #if (ctx instanceof CanvasRenderingContext2D) { res = new jsdom__CanvasRenderingContext2D(ctx); res.ctx = ctx; } - - return res -} - -pub fn (elem HTMLCanvasElement) get_context_2d() CanvasRenderingContext2D { - mut res := CanvasRenderingContext2D{} - #let ctx = elem.node.getContext('2d'); - #res = new jsdom__CanvasRenderingContext2D(ctx); - #res.ctx = ctx; - - return res -} diff --git a/vlib/jsdom/jsdom.js.v b/vlib/jsdom/jsdom.js.v new file mode 100644 index 0000000000..4d9f1825ae --- /dev/null +++ b/vlib/jsdom/jsdom.js.v @@ -0,0 +1,138 @@ +module jsdom + +pub struct CanvasRenderingContext2DSettings { +pub mut: + alpha bool + color_space string + desynchronized bool + will_read_frequently bool +} + +pub interface JS.DOMMatrix2DInit { +mut: + a JS.Number + b JS.Number + c JS.Number + d JS.Number + e JS.Number + f JS.Number + m11 JS.Number + m12 JS.Number + m21 JS.Number + m22 JS.Number + m41 JS.Number + m42 JS.Number +} + +pub interface JS.DOMMatrixInit { + JS.DOMMatrix2DInit + is2D JS.Boolean +mut: + m13 JS.Number + m14 JS.Number + m23 JS.Number + m24 JS.Number + m31 JS.Number + m32 JS.Number + m33 JS.Number + m34 JS.Number + m43 JS.Number + m44 JS.Number +} + +pub interface JS.DOMMatrix { + is2D JS.Boolean + isIdentity JS.Boolean + flipX() JS.DOMMatrix + flipY() JS.DOMMatrix + inverse() JS.DOMMatrix + multiply(other JS.DOMMatrix) JS.DOMMatrix + rotate(rotX JS.Number, rotY JS.Number, rotZ JS.Number) JS.DOMMatrix + rotateAxisAngle(x JS.Number, y JS.Number, z JS.Number, angle JS.Number) JS.DOMMatrix + scale(scaleX JS.Number, scaleY JS.Number, scaleZ JS.Number, originX JS.Number, originY JS.Number, originZ JS.Number) JS.DOMMatrix + scale3d(scale JS.Number, originX JS.Number, originY JS.Number, originZ JS.Number) JS.DOMMatrix + skewX(sx JS.Number) JS.DOMMatrix + skewY(sy JS.Number) JS.DOMMatrix + translate(tx JS.Number, ty JS.Number, tz JS.Number) JS.DOMMatrix + invertSelf() JS.DOMMatrix + multiplySelf(other JS.DOMMatrix) JS.DOMMatrix + preMultiplySelf(other JS.DOMMatrix) JS.DOMMatrix + rotateAxisAngleSelf(x JS.Number, y JS.Number, z JS.Number, angle JS.Number) JS.DOMMatrix + rotateFromVectorSelf(x JS.Number, y JS.Number) JS.DOMMatrix + rotateSelf(rotX JS.Number, rotY JS.Number, rotZ JS.Number) JS.DOMMatrix + scale3dSelf(scale JS.Number, originX JS.Number, originY JS.Number, originZ JS.Number) JS.DOMMatrix + scaleSelf(scaleX JS.Number, scaleY JS.Number, scaleZ JS.Number, originX JS.Number, originY JS.Number, originZ JS.Number) JS.DOMMatrix + toString() JS.String +mut: + a JS.Number + b JS.Number + c JS.Number + d JS.Number + e JS.Number + f JS.Number + m11 JS.Number + m12 JS.Number + m13 JS.Number + m14 JS.Number + m21 JS.Number + m22 JS.Number + m23 JS.Number + m24 JS.Number + m31 JS.Number + m32 JS.Number + m33 JS.Number + m34 JS.Number + m41 JS.Number + m42 JS.Number + m43 JS.Number + m44 JS.Number +} + +pub type SVGMatrix = JS.DOMMatrix +pub type WebKitCSSMatrix = JS.DOMMatrix + +[use_new] +pub fn JS.DOMMatrix.prototype.constructor(init JS.Array) JS.DOMMatrix + +pub interface JS.DOMPoint { + matrixTransform(matrix JS.DOMMatrix) JS.DOMPoint +mut: + w JS.Number + x JS.Number + y JS.Number + z JS.Number +} + +[use_new] +pub fn JS.DOMPoint.prototype.constructor(x JS.Number, y JS.Number, z JS.Number, w JS.Number) JS.DOMPoint + +pub interface JS.DOMQuad { + p1 JS.DOMPoint + p2 JS.DOMPoint + p3 JS.DOMPoint + p4 JS.DOMPoint + getBounds() JS.DOMRect +} + +[use_new] +pub fn JS.DOMQuad.prototype.constructor(p1 JS.DOMPoint, p2 JS.DOMPoint, p3 JS.DOMPoint, p4 JS.DOMPoint) JS.DOMQuad +pub fn JS.DOMQuad.fromQuad(other JS.DOMQuad) JS.DOMQuad +pub fn JS.DOMQuad.fromRect(other JS.DOMRect) JS.DOMRect + +pub interface JS.DOMRect { + bottom JS.Number + left JS.Number + right JS.Number + top JS.Number +mut: + height JS.Number + width JS.Number + x JS.Number + y JS.Number +} + +pub interface JS.DOMStringList { + length JS.Number + contains(JS.String) JS.Boolean + item(index JS.Number) ?JS.String +} diff --git a/vlib/jsdom/jsdom.v b/vlib/jsdom/jsdom.v new file mode 100644 index 0000000000..14d002d1cb --- /dev/null +++ b/vlib/jsdom/jsdom.v @@ -0,0 +1,2 @@ +// DOM API wrapper +module jsdom diff --git a/vlib/jsdom/matrix.js.v b/vlib/jsdom/matrix.js.v deleted file mode 100644 index 6b47623d57..0000000000 --- a/vlib/jsdom/matrix.js.v +++ /dev/null @@ -1,365 +0,0 @@ -module jsdom - -pub interface JS.DOMMatrix { - is_2d JS.Boolean - is_identity JS.Boolean -mut: - m11 JS.Number - m12 JS.Number - m13 JS.Number - m14 JS.Number - m21 JS.Number - m22 JS.Number - m23 JS.Number - m24 JS.Number - m31 JS.Number - m32 JS.Number - m33 JS.Number - m34 JS.Number - m41 JS.Number - m42 JS.Number - m43 JS.Number - m44 JS.Number - a JS.Number - b JS.Number - c JS.Number - d JS.Number - e JS.Number - f JS.Number -} - -pub struct DOMMatrix { -mut: - matrix JS.DOMMatrix = JS.DOMMatrix(voidptr(0)) -} - -pub fn (matrix DOMMatrix) str() string { - fmt := '' - #fmt.str = matrix.matrix + '' - - return fmt -} - -pub fn new_matrix(init []f64) DOMMatrix { - #let tmp = new Array(); - - for val in init { - _ := val - #tmp.push(val); - } - mut m := JS.DOMMatrix(voidptr(0)) - #m = new DOMMatrix(tmp); - - return DOMMatrix{m} -} - -pub fn (m DOMMatrix) invert_self() { - #m.matrix.invertSelf(); -} - -pub fn (m DOMMatrix) multiply_self(other DOMMatrix) { - #m.matrix.multiplySelf(other.matrix); -} - -pub fn (m DOMMatrix) pre_multiply_self(other DOMMatrix) { - #m.matrix.preMultiplySelf(other.matrix); -} - -pub fn (m DOMMatrix) translate_self(tx f64, ty f64, tz f64) { - #m.matrix.translateSelf(tx.val,ty.val,tz.val); -} - -pub fn (m DOMMatrix) scale3d_self(scale f64, origin_x f64, origin_y f64, origin_z f64) { - #m.matrix.scale3dSelf(scale.val,origin_x.val,origin_y.val,origin_z.val) -} - -pub fn (m DOMMatrix) scale_self(scale_x f64, scale_y f64, scale_z f64, origin_x f64, origin_y f64, origin_z f64) { - #m.matrix.scaleSelf(scale_x.val,scale_y.val,scale_z.val,origin_x.val,origin_y.val,origin_z.val); -} - -pub fn (m DOMMatrix) rotate_self(rot_x f64, rot_y f64, rot_z f64) { - #m.matrix.rotateSelf(rot_x.val,rot_y.val,rot_z.val); -} - -pub fn (m DOMMatrix) rotate_axis_angle_self(x f64, y f64, z f64, angle f64) { - #m.matrix.rotateAxisAngleSelf(x.val,y.val,z.val,angle.val); -} - -pub fn (m DOMMatrix) rotate_from_vector_self(x f64, y f64) { - #m.matrix.rotateFromVectorSelf(x.val,y.val); -} - -pub fn (m DOMMatrix) skew_x_self(sx f64) { - #m.matrix.skewXSelf(sx.val); -} - -pub fn (m DOMMatrix) skew_y_self(sy f64) { - #m.matrix.skewYSelf(sy.val); -} - -pub fn (m DOMMatrix) flip_x() DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.flipX(); - - return res -} - -pub fn (m DOMMatrix) flip_y() DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.flipY(); - - return res -} - -pub fn (m DOMMatrix) inverse() DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.inverse(); - - return res -} - -pub fn (m DOMMatrix) multiply(other DOMMatrix) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.multiply(other.matrix); - - return res -} - -pub fn (m DOMMatrix) rotate(rot_x f64, rot_y f64, rot_z f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.rotate(rot_x.val,rot_y.val,rot_z.val); - - return res -} - -pub fn (m DOMMatrix) rotate_axis_angle(x f64, y f64, z f64, angle f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.rotateAxisAngle(x.val,y.val,z.val,angle.val); - - return res -} - -pub fn (m DOMMatrix) rotate_from_vector(x f64, y f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.rotateFromVector(x.val,y.val); - - return res -} - -pub fn (m DOMMatrix) scale(scale_x f64, scale_y f64, scale_z f64, origin_x f64, origin_y f64, origin_z f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.scale(scale_x.val,scale_y.val,scale_z.val,origin_x.val,origin_y.val,origin_z.val); - - return res -} - -pub fn (m DOMMatrix) scale3d(scale f64, origin_x f64, origin_y f64, origin_z f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.scale3d(scale.val, origin_x.val,origin_y.val,origin_z.val); - - return res -} - -pub fn (m DOMMatrix) skew_x(sx f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.skewX(sx.val); - - return res -} - -pub fn (m DOMMatrix) skew_y(sy f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.skewY(sy.val); - - return res -} - -pub fn (m DOMMatrix) translate(tx f64, ty f64, tz f64) DOMMatrix { - res := DOMMatrix{} - #res.matrix = m.matrix.translate(tx.val,ty.val,tz.val); - - return res -} - -pub fn (m DOMMatrix) is_2d() bool { - res := false - #res.val = m.matrix.is2D.val; - - return res -} - -pub fn (m DOMMatrix) a() f64 { - return f64(m.matrix.a) -} - -pub fn (m DOMMatrix) b() f64 { - return f64(m.matrix.b) -} - -pub fn (m DOMMatrix) c() f64 { - return f64(m.matrix.c) -} - -pub fn (m DOMMatrix) d() f64 { - return f64(m.matrix.d) -} - -pub fn (m DOMMatrix) e() f64 { - return f64(m.matrix.e) -} - -pub fn (m DOMMatrix) f() f64 { - return f64(m.matrix.f) -} - -pub fn (mut m DOMMatrix) set_a(a f64) { - m.matrix.a = JS.Number(a) -} - -pub fn (mut m DOMMatrix) set_b(b f64) { - m.matrix.b = JS.Number(b) -} - -pub fn (mut m DOMMatrix) set_c(c f64) { - m.matrix.c = JS.Number(c) -} - -pub fn (mut m DOMMatrix) set_d(d f64) { - m.matrix.d = JS.Number(d) -} - -pub fn (mut m DOMMatrix) set_e(e f64) { - m.matrix.e = JS.Number(e) -} - -pub fn (mut m DOMMatrix) set_f(f f64) { - m.matrix.f = JS.Number(f) -} - -pub fn (m DOMMatrix) m11() f64 { - return f64(m.matrix.m11) -} - -pub fn (m DOMMatrix) m12() f64 { - return f64(m.matrix.m12) -} - -pub fn (m DOMMatrix) m13() f64 { - return f64(m.matrix.m13) -} - -pub fn (m DOMMatrix) m14() f64 { - return f64(m.matrix.m14) -} - -pub fn (m DOMMatrix) m21() f64 { - return f64(m.matrix.m21) -} - -pub fn (m DOMMatrix) m22() f64 { - return f64(m.matrix.m22) -} - -pub fn (m DOMMatrix) m23() f64 { - return f64(m.matrix.m23) -} - -pub fn (m DOMMatrix) m24() f64 { - return f64(m.matrix.m24) -} - -pub fn (m DOMMatrix) m31() f64 { - return f64(m.matrix.m31) -} - -pub fn (m DOMMatrix) m32() f64 { - return f64(m.matrix.m32) -} - -pub fn (m DOMMatrix) m33() f64 { - return f64(m.matrix.m33) -} - -pub fn (m DOMMatrix) m34() f64 { - return f64(m.matrix.m34) -} - -pub fn (m DOMMatrix) m41() f64 { - return f64(m.matrix.m41) -} - -pub fn (m DOMMatrix) m42() f64 { - return f64(m.matrix.m42) -} - -pub fn (m DOMMatrix) m43() f64 { - return f64(m.matrix.m43) -} - -pub fn (m DOMMatrix) m44() f64 { - return f64(m.matrix.m44) -} - -pub fn (mut m DOMMatrix) set_m11(x f64) { - m.matrix.m11 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m12(x f64) { - m.matrix.m12 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m13(x f64) { - m.matrix.m13 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m14(x f64) { - m.matrix.m14 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m21(x f64) { - m.matrix.m21 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m22(x f64) { - m.matrix.m22 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m23(x f64) { - m.matrix.m23 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m24(x f64) { - m.matrix.m24 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m31(x f64) { - m.matrix.m31 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m32(x f64) { - m.matrix.m32 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m33(x f64) { - m.matrix.m33 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m34(x f64) { - m.matrix.m34 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m41(x f64) { - m.matrix.m41 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m42(x f64) { - m.matrix.m42 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m43(x f64) { - m.matrix.m43 = JS.Number(x) -} - -pub fn (mut m DOMMatrix) set_m44(x f64) { - m.matrix.m44 = JS.Number(x) -} diff --git a/vlib/jsdom/path2d.js.v b/vlib/jsdom/path2d.js.v deleted file mode 100644 index 4883d63322..0000000000 --- a/vlib/jsdom/path2d.js.v +++ /dev/null @@ -1,63 +0,0 @@ -module jsdom - -pub struct JS.Path2D {} - -pub fn (p JS.Path2D) addPath(JS.Path2D, JS.DOMMatrix) -pub fn (p JS.Path2D) closePath() -pub fn (p JS.Path2D) moveTo(x JS.Number, y JS.Number) -pub fn (p JS.Path2D) lineTo(x JS.Number, y JS.Number) -pub fn (p JS.Path2D) bezierCurveTo(cp1x JS.Number, cp1y JS.Number, cp2x JS.Number, cp2y JS.Number, x JS.Number, y JS.Number) -pub fn (p JS.Path2D) quadraticCurveTo(cpx JS.Number, cpy JS.Number, x JS.Number, y JS.Number) -pub fn (p JS.Path2D) arc(x JS.Number, y JS.Number, radius JS.Number, startAngle JS.Number, endAngle JS.Number, counter_clockwise JS.Boolean) -pub fn (p JS.Path2D) arcTo(x1 JS.Number, y1 JS.Number, x2 JS.Number, y2 JS.Number, radius JS.Number) -pub fn (p JS.Path2D) ellipse(x JS.Number, y JS.Number, radius_x JS.Number, radius_y JS.Number, rotation JS.Number, start_angle JS.Number, end_angle JS.Number, counter_clockwise JS.Boolean) -pub fn (p JS.Path2D) rect(x JS.Number, y JS.Number, width JS.Number, height JS.Number) - -pub struct Path2D { -mut: - path JS.Path2D [noinit] -} - -pub fn (p Path2D) add_path(p2 Path2D) { - #p.path.addPath(p2.path); -} - -pub fn (p Path2D) add_path_with_transform(p2 Path2D, m DOMMatrix) { - p.path.addPath(p2.path, m.matrix) -} - -pub fn (path Path2D) bezier_curve_to(cp1x f64, cp1y f64, cp2x f64, cp2y f64, x f64, y f64) { - #path.path.bezierCurveTo(cp1x.val,cp1y.val,cp2x.val,cp2y.val, x.val,y.val); -} - -pub fn (path Path2D) quadratic_curve_to(cpx f64, cpy f64, x f64, y f64) { - #path.path.quadraticCurveTo(cpx.val,cpy.val,x.val,y.val); -} - -pub fn (path Path2D) arc(x f64, y f64, radius f64, start_angle f64, end_angle f64, counter_clockwise bool) { - #path.path.arc(x.val,y.val,radius.val,start_angle.val,end_angle.val,counter_clockwise.val) -} - -pub fn (path Path2D) arc_to(x1 f64, y1 f64, x2 f64, y2 f64, radius f64) { - #path.path.arcTo(x1.val,y1.val,x2.val,y2.val,radius.val); -} - -pub fn (path Path2D) ellipse(x f64, y f64, radius_x f64, radius_y f64, rotation f64, start_angle f64, end_angle f64, counter_clockwise bool) { - #path.path.ellipse(x.val,y.val,radius_x.val,radius_y.val,rotation.val,start_angle.val,end_angle.val,counter_clockwise.val); -} - -pub fn (path Path2D) rect(x f64, y f64, width f64, height f64) { - #path.path.rect(x.val,y.val,widht.val,height.val); -} - -pub fn (path Path2D) line_to(x f64, y f64) { - path.path.lineTo(JS.Number(x), JS.Number(y)) -} - -pub fn (path Path2D) move_to(x f64, y f64) { - path.path.lineTo(JS.Number(x), JS.Number(y)) -} - -pub fn (path Path2D) close_path() { - path.path.closePath() -} diff --git a/vlib/jsdom/point.js.v b/vlib/jsdom/point.js.v deleted file mode 100644 index 21997b52c6..0000000000 --- a/vlib/jsdom/point.js.v +++ /dev/null @@ -1,71 +0,0 @@ -module jsdom - -pub struct JS.DOMPoint { -pub mut: - x JS.Number [noinit] - y JS.Number [noinit] - z JS.Number [noinit] - w JS.Number [noinit] -} - -pub struct DOMPoint { -mut: - point JS.DOMPoint -} - -pub fn new_dompoint(x f64, y f64, z f64, w f64) DOMPoint { - mut point := DOMPoint{} - - point.point.x = JS.Number(x) - point.point.y = JS.Number(y) - point.point.z = JS.Number(z) - point.point.w = JS.Number(w) - - return point -} - -pub fn (p DOMPoint) x() f64 { - return f64(p.point.x) -} - -pub fn (p DOMPoint) y() f64 { - return f64(p.point.y) -} - -pub fn (p DOMPoint) z() f64 { - return f64(p.point.z) -} - -pub fn (p DOMPoint) w() f64 { - return f64(p.point.w) -} - -pub fn (mut p DOMPoint) set_x(x f64) { - p.point.x = JS.Number(x) -} - -pub fn (mut p DOMPoint) set_y(y f64) { - p.point.y = JS.Number(y) -} - -pub fn (mut p DOMPoint) set_z(z f64) { - p.point.z = JS.Number(z) -} - -pub fn (mut p DOMPoint) set_w(w f64) { - p.point.w = JS.Number(w) -} - -pub fn (p DOMPoint) matrix_transform(matrix DOMMatrix) DOMPoint { - mut point := DOMPoint{} - #point.point = p.point.matrixTransform(matrix.matrix); - - return point -} - -pub fn (p DOMPoint) matrix_transform_2() DOMPoint { - mut point := DOMPoint{} - #point.point = p.point.matrixTransform(); - - return point -} diff --git a/vlib/jsdom/webgl.js.v b/vlib/jsdom/webgl.js.v deleted file mode 100644 index d500c38fbb..0000000000 --- a/vlib/jsdom/webgl.js.v +++ /dev/null @@ -1,3 +0,0 @@ -module jsdom - -pub struct WebGLRenderingContext {} diff --git a/vlib/jsdom/window.js.v b/vlib/jsdom/window.js.v deleted file mode 100644 index dfecd9d0ce..0000000000 --- a/vlib/jsdom/window.js.v +++ /dev/null @@ -1,15 +0,0 @@ -module jsdom - -pub struct JS.Window { -} - -pub struct Window { - node JS.Window [noinit] -} - -pub fn (elem Window) add_event_listener(event string, cb EventCallback) { - #elem.node.addEventListener(event.str, function (event) { let e = jsdom__dispatch_event_target(this); - #let ev = jsdom__dispatch_event(event); ev.event = event; - #return cb(e,ev) - #}); -} diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5ad9f8c265..d99d75fa6e 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -360,6 +360,7 @@ pub: pos token.Position pre_comments []Comment generic_types []Type + attrs []Attr pub mut: methods []FnDecl fields []StructField @@ -514,6 +515,7 @@ pub mut: is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe) is_keep_alive bool // GC must not free arguments before fn returns is_noreturn bool // whether the function/method is marked as [noreturn] + is_ctor_new bool // if JS ctor calls requires `new` before call, marked as `[use_new]` in V args []CallArg expected_arg_types []Type language Language diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 92619df292..6d6aa2cbf8 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -78,6 +78,7 @@ pub: is_variadic bool language Language is_pub bool + is_ctor_new bool // `[use_new] fn JS.Array.prototype.constructor()` is_deprecated bool // `[deprecated] fn abc(){}` is_noreturn bool // `[noreturn] fn abc(){}` is_unsafe bool // `[unsafe] fn abc(){}` @@ -1298,6 +1299,12 @@ pub fn (t Table) does_type_implement_interface(typ Type, inter_typ Type) bool { return false } if mut inter_sym.info is Interface { + attrs := t.interfaces[inter_typ].attrs + for attr in attrs { + if attr.name == 'single_impl' { + return false + } + } // do not check the same type more than once for tt in inter_sym.info.types { if tt.idx() == typ.idx() { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c995117c9b..240f75d369 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -598,7 +598,7 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) { c.error('field `$field.name` uses non JS type', field.pos) } } - if field.typ == node.typ { + if field.typ == node.typ && node.language != .js { c.error('recursive interface fields are not allowed because they cannot be initialised', field.type_pos) } @@ -765,7 +765,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { c.error('cast to sum type using `${type_sym.name}($sexpr)` not `$type_sym.name{$sexpr}`', node.pos) } - if type_sym.kind == .interface_ { + if type_sym.kind == .interface_ && type_sym.language != .js { c.error('cannot instantiate interface `$type_sym.name`', node.pos) } if type_sym.info is ast.Alias { @@ -2092,6 +2092,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } if has_method { node.is_noreturn = method.is_noreturn + node.is_ctor_new = method.is_ctor_new if !method.is_pub && !c.pref.is_test && method.mod != c.mod { // If a private method is called outside of the module // its receiver type is defined in, show an error. @@ -2696,6 +2697,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } node.is_noreturn = func.is_noreturn + node.is_ctor_new = func.is_ctor_new if !found_in_args { if node.scope.known_var(fn_name) { c.error('ambiguous call to: `$fn_name`, may refer to fn `$fn_name` or variable `$fn_name`', diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index ba1fdf2a6b..8940ebe049 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -1063,6 +1063,7 @@ pub fn (mut f Fmt) hash_stmt(node ast.HashStmt) { } pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) { + f.attrs(node.attrs) if node.is_pub { f.write('pub ') } diff --git a/vlib/v/gen/js/fn.v b/vlib/v/gen/js/fn.v index 57c70077d8..264450305a 100644 --- a/vlib/v/gen/js/fn.v +++ b/vlib/v/gen/js/fn.v @@ -65,6 +65,15 @@ fn (mut g JsGen) js_mname(name_ string) string { fn (mut g JsGen) js_call(node ast.CallExpr) { g.call_stack << node it := node + call_return_is_optional := it.return_type.has_flag(.optional) + if call_return_is_optional { + g.writeln('(function () {') + g.writeln('try {') + g.writeln('let tmp = ') + } + if it.is_ctor_new { + g.write('new ') + } g.write('${g.js_mname(it.name)}(') for i, arg in it.args { g.expr(arg.expr) @@ -74,12 +83,51 @@ fn (mut g JsGen) js_call(node ast.CallExpr) { } // end call g.write(')') + if call_return_is_optional { + g.write(';\n') + g.writeln('if (tmp === null || tmp === undefined) throw "none";') + g.writeln('return tmp;') + g.writeln('} catch(err) {') + g.inc_indent() + // gen or block contents + match it.or_block.kind { + .block { + if it.or_block.stmts.len > 1 { + g.stmts(it.or_block.stmts[..it.or_block.stmts.len - 1]) + } + // g.write('return ') + g.stmt(it.or_block.stmts.last()) + } + .propagate { + panicstr := '`optional not set (\${err + ""})`' + if g.file.mod.name == 'main' && g.fn_decl.name == 'main.main' { + g.writeln('return builtin__panic($panicstr)') + } else { + g.writeln('throw new Option({ state: new byte(2), err: error(new string($panicstr)) });') + } + } + else {} + } + // end catch + g.dec_indent() + g.writeln('}') + g.writeln('})()') + } g.call_stack.delete_last() } fn (mut g JsGen) js_method_call(node ast.CallExpr) { g.call_stack << node it := node + call_return_is_optional := it.return_type.has_flag(.optional) + if call_return_is_optional { + g.writeln('(function () {') + g.writeln('try {') + g.writeln('let tmp = ') + } + if it.is_ctor_new { + g.write('new ') + } g.expr(it.left) g.write('.${g.js_mname(it.name)}(') for i, arg in it.args { @@ -90,6 +138,36 @@ fn (mut g JsGen) js_method_call(node ast.CallExpr) { } // end method call g.write(')') + if call_return_is_optional { + g.write(';\n') + g.writeln('if (tmp === null || tmp === undefined) throw "none";') + g.writeln('return tmp;') + g.writeln('} catch(err) {') + g.inc_indent() + // gen or block contents + match it.or_block.kind { + .block { + if it.or_block.stmts.len > 1 { + g.stmts(it.or_block.stmts[..it.or_block.stmts.len - 1]) + } + // g.write('return ') + g.stmt(it.or_block.stmts.last()) + } + .propagate { + panicstr := '`optional not set (\${err + ""})`' + if g.file.mod.name == 'main' && g.fn_decl.name == 'main.main' { + g.writeln('return builtin__panic($panicstr)') + } else { + g.writeln('throw new Option({ state: new byte(2), err: error(new string($panicstr)) });') + } + } + else {} + } + // end catch + g.dec_indent() + g.writeln('}') + g.writeln('})()') + } g.call_stack.delete_last() } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index e10d8d6111..4574da2059 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -177,10 +177,14 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string { iface := g.table.find_type(iface_name) or { panic('unreachable: interface must exist') } for ty in iface_types { sym := g.table.get_type_symbol(ty) - for method in iface.methods { p_sym := g.table.get_type_symbol(ty) - mname := g.js_name(p_sym.name) + '_' + method.name + + mname := if p_sym.has_method(method.name) { + g.js_name(p_sym.name) + '_' + method.name + } else { + g.js_name(iface_name) + '_' + method.name + } g.write('${g.js_name(sym.name)}.prototype.$method.name = function(') for i, param in method.params { if i == 0 { @@ -3154,8 +3158,23 @@ fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) { fn (mut g JsGen) gen_struct_init(it ast.StructInit) { type_sym := g.table.get_type_symbol(it.typ) name := type_sym.name - if it.fields.len == 0 { + if it.fields.len == 0 && type_sym.kind != .interface_ { g.write('new ${g.js_name(name)}({})') + } else if it.fields.len == 0 && type_sym.kind == .interface_ { + g.write('new ${g.js_name(name)}()') // JS interfaces can be instantiated with default ctor + } else if type_sym.kind == .interface_ && it.fields.len != 0 { + g.writeln('(function () {') + g.inc_indent() + g.writeln('let tmp = new ${g.js_name(name)}()') + + for field in it.fields { + g.write('tmp.$field.name = ') + g.expr(field.expr) + g.writeln(';') + } + g.writeln('return tmp') + g.dec_indent() + g.writeln('})()') } else { g.writeln('new ${g.js_name(name)}({') g.inc_indent() diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index ea2e5e4a8d..caba6d7222 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -186,6 +186,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { mut is_unsafe := false mut is_trusted := false mut is_noreturn := false + mut is_ctor_new := false mut is_c2v_variadic := false for fna in p.attrs { match fna.name { @@ -199,6 +200,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { 'unsafe' { is_unsafe = true } 'trusted' { is_trusted = true } 'c2v_variadic' { is_c2v_variadic = true } + 'use_new' { is_ctor_new = true } else {} } } @@ -446,6 +448,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { is_pub: is_pub is_deprecated: is_deprecated is_noreturn: is_noreturn + is_ctor_new: is_ctor_new is_unsafe: is_unsafe is_main: is_main is_test: is_test diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 7453e6e61c..2d6acd86e2 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -431,6 +431,7 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit { fn (mut p Parser) interface_decl() ast.InterfaceDecl { p.top_level_statement_start() mut pos := p.tok.position() + attrs := p.attrs is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -629,6 +630,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { methods: methods ifaces: ifaces is_pub: is_pub + attrs: attrs pos: pos pre_comments: pre_comments generic_types: generic_types