From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Akira Kyle Newsgroups: gmane.emacs.devel Subject: Re: Introducing emacs-webkit and more thoughts on Emacs rendering (was Rethinking the design of xwidgets) Date: Sun, 22 Nov 2020 20:44:16 -0700 Message-ID: <86eekkohyn.fsf@akirakyle.com> References: <864kmzupp0.fsf@akirakyle.com> <86pn46awrr.fsf@akirakyle.com> <86pn45nrye.fsf@akirakyle.com> <86mtz9nnn2.fsf@akirakyle.com> Mime-Version: 1.0 Content-Type: text/plain; format=flowed Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="37139"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.4.13; emacs 28.0.50 Cc: emacs-devel@gnu.org To: "T.V Raman" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Mon Nov 23 04:44:54 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kh2mb-0009Yk-H8 for ged-emacs-devel@m.gmane-mx.org; Mon, 23 Nov 2020 04:44:53 +0100 Original-Received: from localhost ([::1]:42478 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kh2ma-0008Lp-Jd for ged-emacs-devel@m.gmane-mx.org; Sun, 22 Nov 2020 22:44:52 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:51460) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kh2m5-0007v5-Ms for emacs-devel@gnu.org; Sun, 22 Nov 2020 22:44:21 -0500 Original-Received: from mail-io1-f41.google.com ([209.85.166.41]:44958) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kh2m4-0002YU-3J for emacs-devel@gnu.org; Sun, 22 Nov 2020 22:44:21 -0500 Original-Received: by mail-io1-f41.google.com with SMTP id o11so16575160ioo.11 for ; Sun, 22 Nov 2020 19:44:19 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:references:user-agent:from:to:cc:subject :in-reply-to:date:message-id:mime-version; bh=4RFyPIZXF5a09LxpqCxbUH/J5x8jxTO77y8WQhzj8hk=; b=Qg7YNE2ATNERSwTUgeCizKoywD/dYLMsTaz5rKE/J/bIeuXitLhA4sXaEykCOJLpI2 B65DwFbcUEMRFydhavSyEL47xOV2EFFZzc+SEklNpfNdGXrMptt50w7RXzXscFiGVV9r blcu4j1SSjlvsQQTAynpcdjhA2Sd2Vl8AP7V86IBQ/xgN6ITQyMrBaEKzl0/W1Eu7ddD vBnV5kiBK34tCSiSyIyLh9AqyYJr8zoLcx2cWeQTz0+P0vid+Px0+UPxiX9aD3RqFSyl Dz2fcYq2rwb+IzZlhdPxorHSXCSmdbcNjtntAB0cEtrvf/IY73wI0NuetksCTH/qbC5d 0g1g== X-Gm-Message-State: AOAM533/Z2fsxQOdjZrhLe3cvIYr4tYgfqUBxjoLjqL1Pb37Gl/+LVsZ uQpj3vRjvyvAkOgvkUFv1MylExLzJLYrlYZ5 X-Google-Smtp-Source: ABdhPJzVyBY5srqA2/wh+mtbakKVfR5rvMt8+5g3kf86rMQobEG/KKj2jecUjrzuxMDijUmXfA0W+Q== X-Received: by 2002:a05:6638:d4e:: with SMTP id d14mr388252jak.26.1606103058254; Sun, 22 Nov 2020 19:44:18 -0800 (PST) Original-Received: from data ([2601:281:8080:45f0:faaf:88e1:3993:523]) by smtp.gmail.com with ESMTPSA id p28sm7460047ilb.9.2020.11.22.19.44.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Nov 2020 19:44:17 -0800 (PST) In-reply-to: Received-SPF: pass client-ip=209.85.166.41; envelope-from=aikokyle@gmail.com; helo=mail-io1-f41.google.com X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FORGED_FROMDOMAIN=0.249, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:259663 Archived-At: On Sun, Nov 22, 2020 at 05:46 PM, T.V Raman wrote: > Doing the manipulation with injected jSON would be fin e bye me. > > I did look at parenscript in the context of nyxt, > and it looks interesting, but I dont have anything religious re > the > shape of delimiters I use to write code :-) > > My interest stems primarily from wanting to speak Web content > intelligently and EWW gets me a lot of that, except where Web > Content > is dynamically generated from JS and given that, I'm looking to > get > Webkit to build the DOM, and give it to me in a form that I can > query > it, manipulate it, and finally speak the relevant bits. Here's a proof of concept of that. Don't try it on any large or complicated page as it'll grind Emacs to a halt trying to do the parsing. (setq webkit--to-json-js " function toJSON(node) { let propFix = { for: 'htmlFor', class: 'className' }; let specialGetters = { style: (node) => node.style.cssText, }; let attrDefaultValues = { style: '' }; let obj = { nodeType: node.nodeType, }; if (node.tagName) { obj.tagName = node.tagName.toLowerCase(); } else if (node.nodeName) { obj.nodeName = node.nodeName; } if (node.nodeValue) { obj.nodeValue = node.nodeValue; } let attrs = node.attributes; if (attrs) { let defaultValues = new Map(); for (let i = 0; i < attrs.length; i++) { let name = attrs[i].nodeName; defaultValues.set(name, attrDefaultValues[name]); } // Add some special cases that might not be included by enumerating // attributes above. Note: this list is probably not exhaustive. switch (obj.tagName) { case 'input': { if (node.type === 'checkbox' || node.type === 'radio') { defaultValues.set('checked', false); } else if (node.type !== 'file') { // Don't store the value for a file input. defaultValues.set('value', ''); } break; } case 'option': { defaultValues.set('selected', false); break; } case 'textarea': { defaultValues.set('value', ''); break; } } let arr = []; for (let [name, defaultValue] of defaultValues) { let propName = propFix[name] || name; let specialGetter = specialGetters[propName]; let value = specialGetter ? specialGetter(node) : node[propName]; if (value !== defaultValue) { arr.push([name, value]); } } if (arr.length) { obj.attributes = arr; } } let childNodes = node.childNodes; // Don't process children for a textarea since we used `value` above. if (obj.tagName !== 'textarea' && childNodes && childNodes.length) { let arr = (obj.childNodes = []); for (let i = 0; i < childNodes.length; i++) { arr[i] = toJSON(childNodes[i]); } } return obj; } toJSON(document); ") (defun webkit--save-json (msg) (setq webkit--json (json-parse-string msg))) (webkit--execute-js (with-current-buffer (car webkit--buffers) webkit--id) webkit--to-json-js "webkit--save-json") I think through this general framework one could more efficiently extract the parts of the DOM one is interested in rather than dumping it all into elisp like I did above.