diff --git a/jade-backend.el b/jade-backend.el new file mode 100644 index 0000000..aa53a53 --- /dev/null +++ b/jade-backend.el @@ -0,0 +1,140 @@ +;;; jade-backend.el --- Backend for jade.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Nicolas Petton + +;; Author: Nicolas Petton +;; Keywords: internal + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Generic backend implementation. + +;; Backends should define a new backend symbol using `jade-register-backend', + +;;; Code: + +(require 'map) +(require 'jade-repl) + +(defvar jade-connections (list) "List of connections.") + +(defvar jade-connection nil + "Current connection to the browser tab. + +A connection should be an alist with the following required keys: +`backend' and `url'. Other backend-specific keys might be used +by backends.") +(make-variable-buffer-local 'jade-connection) + +(defvar jade-backend nil + "Current backend used.") +(make-variable-buffer-local 'jade-backend) + +(defvar jade-backends nil "List of registered backends.") + +(defmacro jade-with-connection (connection &rest body) + "Set the value of `jade-connection' to CONNECTION and evaluate BODY." + `(let ((jade-connection ,connection)) + ,@body)) + +(defun jade-register-backend (backend) + "Register a new BACKEND. +BACKEND should be a symbol." + (add-to-list 'jade-backends backend)) + +(defun jade-connect (backend host port) + "Open a connection to BACKEND on HOST:PORT." + (interactive (list (completing-read "Connect to backend: " jade-backends nil t) + (read-from-minibuffer "Host: " "127.0.0.1") + (read-from-minibuffer "Port: " "9222"))) + (jade-backend-connect (intern backend) host port)) + +(cl-defgeneric jade-backend-connect (backend host port) + "Open a connection to BACKEND on HOST:PORT. + +A connection is an alist representing a browser connection. Keys +can vary depending on backend requirements, the only mandatory +key is `url'. + +Once created, the connection should be added to +`jade-connections'.") + +(defun jade-quit () + "Close the current connection and kill its REPL buffer if any." + (interactive) + (unless jade-connection + (user-error "No active connection to close")) + (when (y-or-n-p (format "Do you really want to close the connection to %s ? " + (map-elt jade-connection 'url))) + (jade-backend-close-connection jade-backend jade-connection) + (setq jade-connections (remq jade-connection jade-connections)) + (kill-buffer (jade-repl-get-buffer)))) + +;;; jade-connection methods + +(cl-defgeneric jade-backend-close-connection (backend connection) + "Close CONNECTION.") + +(cl-defgeneric jade-backend-evaluate (backend string &optional callback) + "Evaluate STRING then call CALLBACK. +CALLBACK is called with two arguments, the value returned by the +evaluation and non-nil if the evaluation threw an error. + +The value should be an alist with a the following required keys: +`type', `value' and `description'. If the value represents a +remote object that can be inspected, it should also have an +`objectid' key.") + +(cl-defgeneric jade-backend-get-completions (backend expression prefix callback) + "Get the completion list using CONNECTION for EXPRESSION that match PREFIX. +Evaluate CALLBACK on the filtered candidates. + +EXPRESSION should be a valid JavaScript expression string.") + +(cl-defgeneric jade-backend-get-properties (backend reference &optional callback all-properties) + "Request the properties of the remote object represented by REFERENCE. +REFERENCE must be the id of a remote object. +CALLBACK is called with the fetched list of properties. + +If ALL-PROPERTIES is non-nil, get all the properties from the +prototype chain of the remote object.") + +(cl-defgeneric jade-backend-get-script-source (backend frame callback) + "Get the source of the script for FRAME. +Evaluate CALLBACK with the result.") + +(cl-defgeneric jade-backend-resume (backend &optional callback) + "Resume the debugger and evaluate CALLBACK if non-nil.") + +(cl-defgeneric jade-backend-step-into (backend &optional callback) + "Step into the current stack frame and evaluate CALLBACK if non-nil.") + +(cl-defgeneric jade-backend-step-out (backend &optional callback) + "Step out the current stack frame and evaluate CALLBACK if non-nil.") + +(cl-defgeneric jade-backend-step-over (backend &optional callback) + "Step over the current stack frame and evaluate CALLBACK if non-nil.") + +(cl-defgeneric jade-backend-continue-to-location (backend location &optional callback) + "Continue to LOCATION and evaluate CALLBACK if non-nil. +Location should be an alist with a `column' and `row' key.") + +(defun jade-backend-object-reference-p (value) + "Return non-nil if VALUE is a reference to a remote object." + (map-elt value 'objectid)) + +(provide 'jade-backend) +;;; jade-backend.el ends here diff --git a/jade-chrome.el b/jade-chrome.el new file mode 100644 index 0000000..9fbcf2b --- /dev/null +++ b/jade-chrome.el @@ -0,0 +1,429 @@ +;;; jade-chrome.el --- Chrom{e|ium} backend for jade -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Nicolas Petton + +;; Author: Nicolas Petton +;; Keywords: tools, javascript + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Jade backend implementation for Chrome and Chromium. Currently supports the +;; REPL, code completion, object inspection and the debugger. + +;;; Code: + +(require 'websocket) +(require 'url) +(require 'json) +(require 'map) +(require 'seq) + +(require 'jade-backend) +(require 'jade-repl) +(require 'jade-debugger) + +(defvar jade-chrome-completion-function "function getCompletions(type)\n{var object;if(type===\"string\")\nobject=new String(\"\");else if(type===\"number\")\nobject=new Number(0);else if(type===\"boolean\")\nobject=new Boolean(false);else\nobject=this;var resultSet={};for(var o=object;o;o=o.__proto__){try{if(type===\"array\"&&o===object&&ArrayBuffer.isView(o)&&o.length>9999)\ncontinue;var names=Object.getOwnPropertyNames(o);for(var i=0;i9999)\ncontinue;var names=Object.getOwnPropertyNames(o);for(var i=0;i