erosman / support

Support Location for all my extensions
Mozilla Public License 2.0
170 stars 12 forks source link

[FireMonkey]: Some observations for v1.5 #52

Closed Martii closed 5 years ago

Martii commented 5 years ago

Apologies for not getting here sooner... haven't had much free time to twiddle. Also had to wait until the Fx version was beyond your em:version (don't do beta and earliers now).

Some data for you:

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“style-src”).  70 firemonkey
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). firemonkey:4:1

As the A.M. of OUJS we don't have any such policy yet that I know of... assume CORS and/or the like? or something internal to the extension?

OUJS test script (ref'd below) ... Install button did nothing for interception by FireMonkey... so manually created a new script... pasted in content... This console error may be relevant:

Error: WebExtension context not found! ExtensionParent.jsm:1041:13

Export of preferences:

{
  "autoUpdateInterval": 0,
  "autoUpdateLast": 0,
  "content": {
    "oujs - Meta View": {
      "name": "oujs - Meta View",
      "author": "",
      "description": "Adds a script navigation link next to `Source Code` titled `Meta` and opens a phantom url to show the detected metadata",
      "enabled": false,
      "updateURL": "https://openuserjs.org/meta/Marti/oujs_-_Meta_View.meta.js",
      "autoUpdate": true,
      "version": "4.4.5",
      "allFrames": false,
      "js": "// ==UserScript==\n// @name          oujs - Meta View\n// @namespace     https://openuserjs.org/users/Marti\n// @description   Adds a script navigation link next to `Source Code` titled `Meta` and opens a phantom url to show the detected metadata\n// @copyright     2014+, Marti Martz (https://openuserjs.org/users/Marti)\n// @license       CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode\n// @license       GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt\n// @version       4.4.5\n// @icon          https://www.gravatar.com/avatar/7ff58eb098c23feafa72e0b4cd13f396?r=G&s=48&default=identicon\n \n// @homepageURL  https://github.com/Martii/UserScripts/tree/master/src/oujs/Meta%20View\n// @homepageURL  https://openuserjs.org/scripts/marti/oujs_-_Meta_View\n// @supportURL   https://openuserjs.org/scripts/marti/oujs_-_Meta_View/issues\n \n// @updateURL    https://openuserjs.org/meta/Marti/oujs_-_Meta_View.meta.js\n// @downloadURL  https://openuserjs.org/install/Marti/oujs_-_Meta_View.min.user.js\n \n// @include  /^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//\n// @include  /^http://localhost(?::\\d{1,5})?/scripts//\n \n// @include  https://openuserjs.org/scripts/*/*\n// @include  http://localhost:8080/scripts/*/*\n \n// @grant none\n \n// ==/UserScript==\n \n(function() {\n  'use strict';\n \n  /**\n   *\n   */\n \n  var FQDN = window.location.protocol + '//' + window.location.host;\n \n  var matches = location.pathname.match(/^\\/scripts\\/(.*?)\\/(.*?)(?:$|\\/)/);\n  if (matches) {\n    var\n        userName = matches[1],\n        scriptName = matches[2]\n    ;\n \n    var hookNode;\n    if (/\\/meta$/.test(location.pathname)) { // NOTE: Currently a 404 page\n      var NodeScript = document.createElement('script'); // Watchpoint\n      NodeScript.setAttribute('src', '/redist/npm/ace-builds/src/ace.js');\n      NodeScript.setAttribute('type', 'text/javascript');\n      NodeScript.setAttribute('charset', 'UTF-8');\n \n      var bodyNode = document.querySelector('body');\n      bodyNode.appendChild(NodeScript);\n \n      var panelBodyNode = document.querySelector('div.panel-body');\n      if (panelBodyNode && panelBodyNode.firstChild.nextSibling.textContent == '404') {\n \n        var titleNode = document.head.querySelector('title');\n        if (titleNode)\n          titleNode.textContent = 'Meta ' + scriptName + '| OpenUserJS';\n \n        hookNode = panelBodyNode.parentNode;\n \n        // Reset content\n        while (hookNode.hasChildNodes())\n          hookNode.removeChild(hookNode.firstChild);\n \n        hookNode.classList.remove('panel-default');\n        hookNode.classList.remove('panel');\n        hookNode.classList.add('panel-group');\n \n        // Simulate navbar\n        var navbar2TextStrongNodeB = document.createElement('b');\n        navbar2TextStrongNodeB.textContent = 'Installs:';\n \n        var navbar2TextIconNodeI = document.createElement('i');\n        navbar2TextIconNodeI.classList.add('fa');\n        navbar2TextIconNodeI.classList.add('fa-fw');\n        navbar2TextIconNodeI.classList.add('fa-signal');\n \n        var navbar2TextNodeP = document.createElement('p');\n        navbar2TextNodeP.classList.add('navbar-text');\n        navbar2TextNodeP.classList.add('pull-right');\n        navbar2TextNodeP.classList.add('hidden-xs');\n \n        var navNodeUl = document.createElement('ul');\n        navNodeUl.classList.add('nav');\n        navNodeUl.classList.add('navbar-nav');\n \n        var navNodeA4Span4 = document.createElement('span');\n        navNodeA4Span4.classList.add('badge');\n \n        var navNodeA4 = document.createElement('a');\n        navNodeA4.textContent = 'Issues ';\n        navNodeA4.href = '/scripts/' + userName + '/' + scriptName + '/issues';\n \n        var navNodeLi4 = document.createElement('li');\n \n        var navNodeA3 = document.createElement('a');\n        navNodeA3.textContent = 'Meta';\n        navNodeA3.href = '/scripts/' + userName + '/' + scriptName + '/meta';\n        navNodeA3.classList.add('notranslate');\n        
navNodeA3.setAttribute('translate', 'no');\n \n        var navNodeLi3 = document.createElement('li');\n        navNodeLi3.classList.add('active');\n \n        var navNodeA2 = document.createElement('a');\n        navNodeA2.textContent = 'Source Code';\n        navNodeA2.href = '/scripts/' + userName + '/' + scriptName + '/source';\n \n        var navNodeLi2 = document.createElement('li');\n \n        var navNodeA1 = document.createElement('a');\n        navNodeA1.textContent = 'About';\n        navNodeA1.href = '/scripts/' + userName + '/' + scriptName;\n \n        var navNodeLi1 = document.createElement('li');\n \n        var navbarCollapseNodeDiv = document.createElement('div');\n        navbarCollapseNodeDiv.classList.add('navbar-collapse');\n        navbarCollapseNodeDiv.classList.add('collapse');\n        navbarCollapseNodeDiv.classList.add('in');\n        navbarCollapseNodeDiv.id = 'content-navbar';\n \n        var navbar1TextStrongNodeB = document.createElement('b');\n        navbar1TextStrongNodeB.textContent = 'Installs:';\n \n        var navbar1TextIconNodeI = document.createElement('i');\n        navbar1TextIconNodeI.classList.add('fa');\n        navbar1TextIconNodeI.classList.add('fa-fw');\n        navbar1TextIconNodeI.classList.add('fa-signal');\n \n        var navbar1TextNodeP = document.createElement('p');\n        navbar1TextNodeP.classList.add('navbar-text');\n        navbar1TextNodeP.classList.add('visible-xs');\n \n        var navbarBrandNodeDiv = document.createElement('div');\n        navbarBrandNodeDiv.classList.add('navbar-brand');\n        navbarBrandNodeDiv.classList.add('visible-xs');\n \n        var navbarToggleIconNodeI = document.createElement('i');\n        navbarToggleIconNodeI.classList.add('fa');\n        navbarToggleIconNodeI.classList.add('fa-bars');\n \n        var navbarToggleNodeButton = document.createElement('button');\n        navbarToggleNodeButton.type = 'button';\n        navbarToggleNodeButton.setAttribute('data-toggle', 'collapse');\n        navbarToggleNodeButton.setAttribute('data-target', '#content-navbar');\n        navbarToggleNodeButton.classList.add('navbar-toggle');\n \n        var navbarHeaderNodeDiv = document.createElement('div');\n        navbarHeaderNodeDiv.classList.add('navbar-header');\n \n        var navbarNodeNav = document.createElement('nav');\n        navbarNodeNav.classList.add('navbar');\n        navbarNodeNav.classList.add('navbar-default');\n        navbarNodeNav.classList.add('navbar-static-top');\n        navbarNodeNav.setAttribute('role', 'navigation'); // Watchpoint\n \n        // Piece elements together\n        navbarNodeNav.appendChild(navbarHeaderNodeDiv);\n        navbarHeaderNodeDiv.appendChild(navbarToggleNodeButton);\n        navbarToggleNodeButton.appendChild(navbarToggleIconNodeI);\n        navbarHeaderNodeDiv.appendChild(navbarBrandNodeDiv);\n        navbarHeaderNodeDiv.appendChild(navbar1TextNodeP);\n        navbar1TextNodeP.appendChild(navbar1TextIconNodeI);\n        navbar1TextNodeP.appendChild(navbar1TextStrongNodeB);\n \n        navbarNodeNav.appendChild(navbarCollapseNodeDiv);\n        navbarCollapseNodeDiv.appendChild(navNodeUl);\n        navNodeUl.appendChild(navNodeLi1);\n        navNodeLi1.appendChild(navNodeA1);\n        navNodeUl.appendChild(navNodeLi2);\n        navNodeLi2.appendChild(navNodeA2);\n        navNodeUl.appendChild(navNodeLi3);\n        navNodeLi3.appendChild(navNodeA3);\n        navNodeUl.appendChild(navNodeLi4);\n        navNodeLi4.appendChild(navNodeA4);\n        navNodeA4.appendChild(navNodeA4Span4);\n \n        navbarCollapseNodeDiv.appendChild(navbar2TextNodeP);\n \n        navbar2TextNodeP.appendChild(navbar2TextIconNodeI);\n        navbar2TextNodeP.appendChild(navbar2TextStrongNodeB);\n \n        // Simulate the page-heading\n        var scriptNameNodeA = document.createElement('a');\n        scriptNameNodeA.classList.add('script-name');\n        scriptNameNodeA.href = '/scripts/' + userName + '/' + scriptName;\n        scriptNameNodeA.textContent = '\\u2003';\n \n        var pathDividerNodeSpan = 
document.createElement('span');\n        pathDividerNodeSpan.classList.add('path-divider');\n        pathDividerNodeSpan.textContent = '\\u2003';\n \n        var scriptAuthorNodeA = document.createElement('a');\n        scriptAuthorNodeA.classList.add('script-author');\n        scriptAuthorNodeA.href = '/users/' + userName;\n        scriptAuthorNodeA.textContent = '\\u2003';\n \n        var pageHeadingNodeH2 = document.createElement('h2');\n        pageHeadingNodeH2.classList.add('page-heading');\n \n        // Piece elements together\n        pageHeadingNodeH2.appendChild(document.createTextNode(' '));\n        pageHeadingNodeH2.appendChild(scriptAuthorNodeA);\n        pageHeadingNodeH2.appendChild(document.createTextNode(' '));\n        pageHeadingNodeH2.appendChild(pathDividerNodeSpan);\n        pageHeadingNodeH2.appendChild(document.createTextNode(' '));\n        pageHeadingNodeH2.appendChild(scriptNameNodeA);\n \n        // Place parts into the DOM\n        hookNode.parentNode.insertBefore(navbarNodeNav, hookNode.parentNode.firstChild);\n        hookNode.parentNode.insertBefore(pageHeadingNodeH2, hookNode.parentNode.firstChild);\n \n        var NodeDiv = document.createElement('div');\n        NodeDiv.classList.add('alert');\n        NodeDiv.classList.add('alert-warning');\n \n        var NodeStrong = document.createElement('strong');\n        NodeStrong.textContent = 'PLEASE WAIT';\n \n        var NodeText = document.createTextNode(': Fetching the meta.js');\n \n        NodeDiv.appendChild(NodeStrong);\n        NodeDiv.appendChild(NodeText);\n \n        hookNode.appendChild(NodeDiv);\n \n        var url = FQDN + '/src/scripts/' + userName + '/' + scriptName + '.user.js';\n \n        var req = new XMLHttpRequest();\n        req.open('GET', url);\n        req.setRequestHeader('Accept', 'text/x-userscript-meta');\n \n        req.onreadystatechange = function () {\n          function hasRelative(aPrefix) {\n            aPrefix = aPrefix || '';\n \n            var hasCalc = document.createElement('div');\n            hasCalc.style.setProperty(aPrefix + 'width', 'calc(1px)', '');\n \n            var hasUnitV = document.createElement(\"div\");\n            hasUnitV.style.setProperty(aPrefix + \"width\", \"calc(5vw + 5vw)\", \"\");\n \n            return !!hasCalc.style.length && !!hasUnitV.style.length;\n          }\n \n          function hasOurRelative() {\n            return hasRelative('-moz-') || hasRelative('-ms-') || hasRelative('-o-') || hasRelative('-webkit-') || hasRelative();\n          }\n \n          function calcHeight() {\n            return parseInt((window.innerHeight - 306) / 2.004);\n          }\n \n          if (this.readyState == this.DONE) {\n            console.log(\n              [\n                'META VIEW REQUEST SUMMARY',\n                '',\n                'status: ' + this.status,\n                'statusText: ' + this.statusText,\n                'readyState: ' + this.readyState,\n                'getAllResponseHeaders():\\n' + this.getAllResponseHeaders().split('\\n').map(function (aE, aI, aA) {\n                  return '  ' + aE;\n                }).join('\\n'),\n                'responseURL: ' + this.responseURL\n \n              ].join('\\n')\n            );\n \n            switch (this.status) {\n              case 200:\n                if (!this.responseText) {\n                  NodeDiv.classList.remove('alert-warning');\n                  NodeDiv.classList.add('alert-danger');\n                  NodeStrong.textContent = \"FAILURE: \";\n                  NodeText.textContent = \"Unable to retrieve the meta text. `responseText` is absent.\";\n                  return;\n                }\n \n                var responseTextMetaJS = this.responseText.trim();\n \n                NodeText.textContent = \": Fetching the meta.json\";\n \n                url = FQDN + '/meta/' + userName + '/' + scriptName + '.meta.json';\n \n                var req = new XMLHttpRequest();\n                req.open('GET', url);\n \n                req.onreadystatechange = function () {\n                  
if (this.readyState == this.DONE) {\n                    switch (this.status) {\n                      case 200:\n                        if (!this.responseText) {\n                          NodeDiv.classList.remove('alert-warning');\n                          NodeDiv.classList.add('alert-danger');\n                          NodeStrong.textContent = \"FAILURE: \";\n                          NodeText.textContent = \"Unable to retrieve the meta JSON. `responseText` is absent.\";\n                          return;\n                        }\n \n                        var responseTextMetaJSON = this.responseText;\n \n                        var meta = JSON.parse(responseTextMetaJSON);\n \n                        NodeText.textContent = \": Simulating Source Code page\";\n \n                        // Simulate a Source Code page\n                        var NodeStyle = document.createElement('style');\n                        NodeStyle.setAttribute('type', 'text/css');\n                        var min_height = 85.2;\n                        var offset = 306;\n                        var textSVGMetaJS = 'data:image/svg+xml;base64,' + window.btoa([\n                          '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 -200 14.482108 52.124682\" height=\"52.12\">',\n                            '<g fill=\"#ccc\">',\n                              '<path d=\"m9.668-150.24q-.36-.36-.36-.875 0-.515.36-.875.36-.36.875-.36.515 0 .875.36.36.36.36.875 0 .515-.36.875-.36.36-.875.36-.515 0-.875-.36\"/>',\n                              '<path d=\"m3.241-160.82q0-2.128 2.265-2.128h6.28v2.299h-6.555q-.137 0-.24.094-.103.094-.103.232v.738q0 .137.103.232.103.094.24.094h6.555v2.299h-6.555q-.137 0-.24.094-.103.094-.103.232v.738q0 .137.103.232.103.094.24.094h6.555v2.299h-8.374v-2.093h.429q-.601-.532-.601-1.613v-.154q0-1.27.789-1.767-.789-.532-.789-1.767v-.154\"/>',\n                              '<path d=\"m3.051-168.11q0-2.128 2.265-2.128h2.711v3.895h1.75q.137 0 .24-.094.103-.094.103-.232v-.944q0-.137-.103-.232-.103-.094-.24-.094h-.927v-2.299h.652q2.265 0 2.265 2.128v1.939q0 2.128-2.265 2.128h-4.187q-2.265 0-2.265-2.128v-1.939m3.466 1.767v-1.596h-1.544q-.137 0-.24.094-.103.094-.103.232v.944q0 .137.103.232.103.094.24.094h1.544\"/>',\n                              '<path d=\"m10.288-174.6v-.686h1.493v1.613q0 2.128-2.265 2.128h-8.099v-2.299h1.819v-1.441h1.664v1.441h4.564q.48 0 .652-.189.172-.189.172-.566\"/>',\n                              '<path d=\"m3.236-180.91v-1.939h8.374v1.939h-.618q.789.532.789 1.767v.36q0 2.128-2.265 2.128h-4.187q-2.265 0-2.265-2.128v-.36q0-1.235.789-1.767h-.618m6.555.36h-4.736q-.137 0-.24.094-.103.094-.103.232v.944q0 .137.103.232.103.094.24.094h4.736q.137 0 .24-.094.103-.094.103-.232v-.944q0-.137-.103-.232-.103-.094-.24-.094\"/>',\n                              '<path d=\"m9.672-184.36q-.36-.36-.36-.875 0-.515.36-.875.36-.36.875-.36.515 0 .875.36.36.36.36.875 0 .515-.36.875-.36.36-.875.36-.515 0-.875-.36\"/>',\n                              '<path d=\"m11.977-188.26h-8.768v-2.299h9.01q2.265 0 2.265 2.128v1.39h-1.682v-.463q0-.377-.172-.566-.172-.189-.652-.189m-9.455-1.15q0 .515-.369.892-.369.377-.892.377-.523 0-.892-.377-.369-.377-.369-.892 0-.515.369-.884.369-.369.901-.369.532 0 .892.369.36.369.36.884\"/>',\n                              '<path d=\"m6.325-195.87q0-2.128 2.265-2.128h.892q2.265 0 2.265 2.128v1.905q0 2.128-2.265 2.128h-.532v-2.128h.755q.137 0 .24-.094.103-.094.103-.232v-1.407q0-.137-.103-.232-.103-.094-.24-.094h-1.03q-.137 0-.24.094-.103.094-.103.232v1.767q0 2.128-2.265 2.128h-.772q-2.265 0-2.265-2.128v-1.802q0-2.128 2.265-2.128h.309v2.128h-.532q-.137 0-.24.094-.103.094-.103.232v1.304q0 .137.103.232.103.094.24.094h.909q.137 0 .24-.094.103-.094.103-.232v-1.767\"/>',\n                            '</g>',\n                          '</svg>'\n                        ].join(''));\n \n                        var textSVGMetaJSON = 'data:image/svg+xml;base64,' + window.btoa([\n                          '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 -200 14.48211 66.085035\" height=\"66.09\">',\n    
                        '<g fill=\"#ccc\">',\n                              '<path d=\"m9.668-136.28q-.36-.36-.36-.875 0-.515.36-.875.36-.36.875-.36.515 0 .875.36.36.36.36.875 0 .515-.36.875-.36.36-.875.36-.515 0-.875-.36\"/>',\n                              '<path d=\"m3.241-146.86q0-2.128 2.265-2.128h6.28v2.299h-6.555q-.137 0-.24.094-.103.094-.103.232v.738q0 .137.103.232.103.094.24.094h6.555v2.299h-6.555q-.137 0-.24.094-.103.094-.103.232v.738q0 .137.103.232.103.094.24.094h6.555v2.299h-8.374v-2.093h.429q-.601-.532-.601-1.613v-.154q0-1.27.789-1.767-.789-.532-.789-1.767v-.154\"/>',\n                              '<path d=\"m3.051-154.15q0-2.128 2.265-2.128h2.711v3.895h1.75q.137 0 .24-.094.103-.094.103-.232v-.944q0-.137-.103-.232-.103-.094-.24-.094h-.927v-2.299h.652q2.265 0 2.265 2.128v1.939q0 2.128-2.265 2.128h-4.187q-2.265 0-2.265-2.128v-1.939m3.466 1.767v-1.596h-1.544q-.137 0-.24.094-.103.094-.103.232v.944q0 .137.103.232.103.094.24.094h1.544\"/>',\n                              '<path d=\"m10.288-160.64v-.686h1.493v1.613q0 2.128-2.265 2.128h-8.099v-2.299h1.819v-1.441h1.664v1.441h4.564q.48 0 .652-.189.172-.189.172-.566\"/>',\n                              '<path d=\"m3.236-166.95v-1.939h8.374v1.939h-.618q.789.532.789 1.767v.36q0 2.128-2.265 2.128h-4.187q-2.265 0-2.265-2.128v-.36q0-1.235.789-1.767h-.618m6.555.36h-4.736q-.137 0-.24.094-.103.094-.103.232v.944q0 .137.103.232.103.094.24.094h4.736q.137 0 .24-.094.103-.094.103-.232v-.944q0-.137-.103-.232-.103-.094-.24-.094\"/>',\n                              '<path d=\"m9.672-170.4q-.36-.36-.36-.875 0-.515.36-.875.36-.36.875-.36.515 0 .875.36.36.36.36.875 0 .515-.36.875-.36.36-.875.36-.515 0-.875-.36\"/>',\n                              '<path d=\"m11.977-174.3h-8.768v-2.299h9.01q2.265 0 2.265 2.128v1.39h-1.682v-.463q0-.377-.172-.566-.172-.189-.652-.189m-9.455-1.15q0 .515-.369.892-.369.377-.892.377-.523 0-.892-.377-.369-.377-.369-.892 0-.515.369-.884.369-.369.901-.369.532 0 .892.369.36.369.36.884\"/>',\n                              '<path d=\"m6.325-181.91q0-2.128 2.265-2.128h.892q2.265 0 2.265 2.128v1.905q0 2.128-2.265 2.128h-.532v-2.128h.755q.137 0 .24-.094.103-.094.103-.232v-1.407q0-.137-.103-.232-.103-.094-.24-.094h-1.03q-.137 0-.24.094-.103.094-.103.232v1.767q0 2.128-2.265 2.128h-.772q-2.265 0-2.265-2.128v-1.802q0-2.128 2.265-2.128h.309v2.128h-.532q-.137 0-.24.094-.103.094-.103.232v1.304q0 .137.103.232.103.094.24.094h.909q.137 0 .24-.094.103-.094.103-.232v-1.767\"/>',\n                              '<path d=\"m5.305-190.99h4.197q2.271 0 2.271 2.133v1.944q0 2.133-2.271 2.133h-4.197q-2.271 0-2.271-2.133v-1.944q0-2.133 2.271-2.133m4.679 2.305h-5.178q-.138 0-.241.095-.103.095-.103.232v.946q0 .138.103.232.103.095.241.095h5.178q.138 0 .241-.095.103-.095.103-.232v-.946q0-.138-.103-.232-.103-.095-.241-.095\"/>',\n                              '<path d=\"m11.786-194v2.36h-8.595v-2.149h.44q-.616-.546-.616-1.656v-.37q0-2.184 2.325-2.184h6.446v2.36h-6.728q-.141 0-.247.097-.106.097-.106.238v.969q0 .141.106.238.106.097.247.097h6.728\"/>',\n                            '</g>',\n                          '</svg>'\n                        ].join(''));\n \n                        NodeStyle.textContent =\n                          [\n                            '#mdb { min-height: 115px; overflow: auto; }',\n                            '#json { min-height: 115px; height: -moz-calc(' + min_height + 'vh - ' + offset + 'px); height: -o-calc(' + min_height + 'vh - ' + offset + 'px); height: -webkit-calc(' + min_height + 'vh - ' + offset + 'px); height: calc(' + min_height + 'vh - ' + offset + 'px); overflow: auto; }',\n                            '.path-divider { color: #666; margin: 0 0.25em; }',\n                            '#mdb .ace_gutter { background: #ebebeb url(' + textSVGMetaJS + ') repeat-y scroll left top !important; }',\n                            '#json .ace_gutter { background: #ebebeb url(' + textSVGMetaJSON + ') repeat-y scroll left top !important; }',\n \n \n                          ].join('\\n')\n                        ;\n                        document.head.appendChild(
NodeStyle);\n \n                        // Fix title to be native\n                        var scriptNameX = null;\n                        meta.UserScript['name'].forEach(function (e, i, a) {\n                          if (!e.locale) { // Default to absent locale... requirement of OUJS to have `@name`\n                            scriptNameX = e.value;\n                          }\n                        });\n \n                        titleNode.textContent = 'Meta ' + scriptNameX + ' | OpenUserJS';\n \n                        // Create meta views\n                        var jsonNodePre = document.createElement('pre');\n                        jsonNodePre.classList.add('ace_editor');\n                        jsonNodePre.classList.add('ace-dawn');\n                        jsonNodePre.id = 'json';\n                        jsonNodePre.textContent = JSON.stringify(meta, null, ' ');\n \n                        var mdbNodePre = document.createElement('pre');\n                        mdbNodePre.classList.add('ace_editor');\n                        mdbNodePre.classList.add('ace-dawn');\n                        mdbNodePre.id = 'mdb';\n                        mdbNodePre.textContent = responseTextMetaJS;\n \n                        var atIcon = meta.UserScript['icon'];\n                        if (atIcon) {\n                          atIcon = meta.UserScript['icon'][0].value;\n \n                          var pageHeadingIconNodeSpan = document.createElement('span');\n                          pageHeadingIconNodeSpan.classList.add('page-heading-icon');\n                          pageHeadingIconNodeSpan.setAttribute('data-icon-src', atIcon);\n \n                          var pageHeadingIconNodeI = document.createElement('i');\n                          pageHeadingIconNodeI.classList.add('fa');\n                          pageHeadingIconNodeI.classList.add('fa-fw');\n                          pageHeadingIconNodeI.classList.add('fa-file-code-o');\n \n                          pageHeadingNodeH2.insertBefore(pageHeadingIconNodeSpan, pageHeadingNodeH2.firstChild);\n                          pageHeadingIconNodeSpan.appendChild(pageHeadingIconNodeI);\n \n                          var scriptIconNodeImg = document.createElement('img');\n                          scriptIconNodeImg.addEventListener('load', function () {\n                            pageHeadingIconNodeSpan.removeChild(pageHeadingIconNodeI);\n                            pageHeadingIconNodeSpan.appendChild(scriptIconNodeImg);\n                          });\n                          scriptIconNodeImg.src = atIcon;\n                        }\n \n                        scriptAuthorNodeA.textContent = decodeURI(userName);\n                        pathDividerNodeSpan.textContent = \"/\";\n                        scriptNameNodeA.textContent = scriptNameX;\n \n                        var issueCount =\n                          meta.OpenUserJS &&\n                            meta.OpenUserJS.issues &&\n                              meta.OpenUserJS.issues[0] &&\n                                typeof meta.OpenUserJS.issues[0].value !== 'undefined'\n                                  ? meta.OpenUserJS.issues[0].value\n                                  : 'n/a';\n \n                        navNodeA4Span4.textContent = issueCount;\n \n                        var installCount =\n                          meta.OpenUserJS &&\n                            meta.OpenUserJS.installs &&\n                              meta.OpenUserJS.installs[0] &&\n                                typeof meta.OpenUserJS.installs[0].value !== 'undefined'\n                                  ? meta.OpenUserJS.installs[0].value\n                                  : 'n/a';\n \n                        navbar1TextNodeP.appendChild(document.createTextNode(' ' + installCount));\n                        navbar2TextNodeP.appendChild(document.createTextNode(' ' + installCount));\n \n \n                        hookNode.appendChild(mdbNodePre);\n                        hookNode.appendChild(jsonNodePre);\n \n                        
var wrappedNodeInput =  document.createElement('input');\n                        wrappedNodeInput.classList.add('btn');\n                        wrappedNodeInput.classList.add('btn-success');\n                        wrappedNodeInput.id = 'wrap';\n                        wrappedNodeInput.setAttribute('value', 'Wrap');\n                        wrappedNodeInput.type = 'button';\n \n                        var thisAce = (typeof ace !== 'undefined' ? ace : (window.wrappedJSObject ? window.wrappedJSObject.ace : null));\n \n                        if (!thisAce) {\n                          wrappedNodeInput.setAttribute('disabled', 'disabled');\n                        }\n \n                        wrappedNodeInput.addEventListener('click', function (aE) {\n                          var active = false;\n \n                          if (document.querySelector('pre#mdb')) {\n                            if (thisAce.edit('mdb').getSession().getUseWrapMode()) {\n                              thisAce.edit('mdb').getSession().setUseWrapMode(false);\n                            }\n                            else {\n                              thisAce.edit('mdb').getSession().setUseWrapMode(true);\n                              active = true;\n                            }\n                          }\n \n                          if (document.querySelector('pre#json')) {\n                            if (thisAce.edit('json').getSession().getUseWrapMode()) {\n                              thisAce.edit('json').getSession().setUseWrapMode(false);\n                            }\n                            else {\n                              thisAce.edit('json').getSession().setUseWrapMode(true);\n                              active = true;\n                            }\n                          }\n \n                          if (active) {\n                            aE.target.classList.add('active');\n                          } else {\n                            aE.target.classList.remove('active');\n                          }\n \n                          aE.target.blur();\n                        });\n \n                        var toolbarNodeDiv = document.createElement('div');\n                        toolbarNodeDiv.classList.add('btn-toolbar');\n \n                        toolbarNodeDiv.appendChild(wrappedNodeInput);\n \n                        hookNode.appendChild(toolbarNodeDiv);\n \n \n                        // Clean up\n                        hookNode.removeChild(NodeDiv);\n \n                        // Resize for older browsers\n                        if (!hasOurRelative()) {\n                          mdbNodePre.style.setProperty('height', calcHeight() + 'px', '');\n                          jsonNodePre.style.setProperty('height', calcHeight() + 'px', '');\n \n                          if (window.addEventListener) {\n                            window.addEventListener('resize', function () {\n                              mdbNodePre.style.setProperty('height', calcHeight() + 'px', '');\n                              jsonNodePre.style.setProperty('height', calcHeight() + 'px', '');\n                            }, false);\n                          }\n                          else if (window.attachEvent) {\n                            window.addEventListener('resize', function () {\n                              mdbNodePre.style.setProperty('height', calcHeight() + 'px', '');\n                              jsonNodePre.style.setProperty('height', calcHeight() + 'px', '');\n                            });\n                          }\n                        }\n \n                        // Activate Ace\n                        if (thisAce) {\n                          var mdb = thisAce.edit('mdb');\n                          mdb.setTheme('ace/theme/dawn');\n                          mdb.getSession().setMode('ace/mode/javascript');\n                          mdb.container.style.fontFamily = \"monospace\";\n                          mdb.setReadOnly(true);\n \n                          var mdj = thisAce.edit('json');
\n                          mdj.setTheme('ace/theme/dawn');\n                          mdj.getSession().setMode('ace/mode/javascript');\n                          mdj.container.style.fontFamily = \"monospace\";\n                          mdj.setReadOnly(true);\n                        }\n \n                        break;\n                      default:\n                        NodeDiv.classList.remove('alert-warning');\n                        NodeDiv.classList.add('alert-danger');\n \n                        NodeStrong.textContent = 'ERROR';\n                        NodeText.textContent = ': Unable to fetch the meta.json with status of: ' + this.status + this.statusText +\n                          (this.status === 429 ? '. Try again in ' + (this.getResponseHeader('Retry-After') ? this.getResponseHeader('Retry-After') + ' seconds.' : 'a few.') : '');\n                        break;\n                    }\n                  }\n                };\n                req.send();\n \n                break;\n              default:\n                NodeDiv.classList.remove('alert-warning');\n                NodeDiv.classList.add('alert-danger');\n \n                NodeStrong.textContent = 'ERROR';\n                NodeText.textContent = ': Unable to fetch the meta.js with status of: ' + this.status + ' ' + this.statusText +\n                  (this.status === 429 ? '. Try again in ' + (this.getResponseHeader('Retry-After') ? this.getResponseHeader('Retry-After') + ' seconds.' : 'a few.') : '');\n \n                break;\n            }\n          }\n        };\n        req.send();\n      }\n    }\n    else {\n      var sourceNode = document.querySelector('#content-navbar ul.nav li a[href$=\"/source\"]');\n      if (sourceNode) {\n        hookNode = sourceNode.parentNode.parentNode;\n \n        var NodeA = document.createElement('a');\n        NodeA.href = '/scripts/' + userName + '/' + scriptName + '/meta';\n        NodeA.textContent = 'Meta';\n        NodeA.classList.add('notranslate');\n        NodeA.setAttribute('translate', 'no');\n \n        var NodeLi = document.createElement('li');\n        NodeLi.appendChild(NodeA);\n \n        hookNode.insertBefore(NodeLi, sourceNode.parentNode.nextSibling.nextSibling);\n      }\n    }\n  }\n \n})();",
      "css": "",
      "matches": [
        "/^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//",
        "/^http://localhost(?::\\d{1,5})?/scripts//",
        "https://openuserjs.org/scripts/*/*",
        "http://localhost:8080/scripts/*/*"
      ],
      "excludeMatches": [],
      "includeGlobs": [],
      "excludeGlobs": [],
      "matchAboutBlank": false,
      "runAt": "document_idle",
      "error": "Type error for parameter userScriptOptions (Error processing matches.0: Value \"/^https?://openuserjs\\\\.org(?::\\\\d{1,5})?/scripts//\" must either: be one of [\"<all_urls>\"], must either [match the pattern /^(https?|wss?|file|ftp|\\*):\\/\\/(\\*|\\*\\.[^*/]+|[^*/]+)\\/.*$/, or match the pattern /^file:\\/\\/\\/.*$/], or match the pattern /^resource:\\/\\/(\\*|\\*\\.[^*/]+|[^*/]+)\\/.*$|^about:/) for userScripts.register."
    }
  },
  "template": {
    "css": "",
    "js": ""
  }
}

Went to see if the editor had any settings I missed first quick glance... check box for "Enabled" said it was unticked. Ticked it... reloaded web page... new tab load... both not injecting.

Do see your JSON error on the regular expression includes... should skip over those if your extension doesn't support them... perhaps the main issue.

Bottom line... doesn't seem to inject .user.js yet I think in this use case.

Have not tested UserCSS yet. Scripts are more important to me. :)

Interface is snappy (very nice)... perhaps needs more tooltips eventually under "Script & CSS" panel/sidebar so I know what they do without blindly clicking and seeing what explodes/works. ;) Those icons could use a little larger for high DPI screens... mines not and I have to look pretty close to my monitor just to see what they are. Duplicate, I think of scripts and css with respective checkbox for example is something I can't immediately figure out with more in-depth testing.

Anyhow... looking forward to updates to test and any feedback you want me to try. I don't have a whole lot of time to examine in-depth WebExtensions since the site keeps me very busy... but I'll try to try. :smile_cat:

System:

\/laundry list (hope you don't mind this for a start)

erosman commented 5 years ago

Apologies for not getting here sooner

Not at all .. thank you for taking the time to look into it

To start with, Firefox has postponed the official release of the new API to 68 (from 65) therefore as mentioned on the description, the API in FF65-67 requires:

Note: The Official release of the API has been postponed to FF67. The API can be manually enabled for Firefox 65 & 66 users via about:config?filter=extensions.webextensions.userScripts.enabled The API is enabled by default on Nightly.

FireFox API does not support RegEx matches and FireMonkey is adhering to Firefox API standard. You should have seen a red cross next to the script name to show it and there is a notification when clicking to show the script in the editor.

// @include  /^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//
// @include  /^http://localhost(?::\\d{1,5})?/scripts//

AFA button icon, they are ALL Unicode text and not icons per se. Their quality is not as great as proper icon but then the are scalable and added for extra context only.

I have also explained all the buttons in the Help section.

Please let me know if above was helpful.

Martii commented 5 years ago

about:config?filter=extensions.webextensions.userScripts.enabled

plus a restart of the browser.

A typical way of end users disabling metadata block keys of:

// @include  /^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//
// @include  /^http://localhost(?::\\d{1,5})?/scripts//

... is to do this:

//@include  /^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//
//@include  /^http://localhost(?::\\d{1,5})?/scripts//

... which isn't working... Fx via your extension is still parsing it... which is incorrect spec for all .user.js engines including GM, GM Port, and TM. As I mentioned before your extension should probably parse the UserScript metadata block first then send it off to the Fx API. You'll encounter a lot of resistance from the diverse community on this one with people saying they won't do one engine or the other. Once I completely removed the lines then it injected.

NOTE Second retest... continues to FAIL

ALL Unicode text and not icons per se. Their quality is not as great as proper icon but then the are scalable

Nice tip... Ctrl + + here I come! :smile_cat:

You should have seen a red cross next to the script name to show

The X yes... I consider a cross to be ✝ but I'll add a mental note that you mean 🞮

... and there is a notification when clicking to show the script in the editor.

Seem to be missing this part.

Related to the editor at one point during the removal of the space between // @include and //@include lost the line numbers too... rendering issue... Leaving focus of Fx reshows the numbers and re-increments them. Very unusual bug. Even went past the left margin (several characters before it).

Firefox has postponed the official release of the new API to 68

Surprise, surprise :smile_cat:

and added for extra context only

Syncing up with my terminology... list filters ... would never have guessed that even with reading the Help. :smile_cat: With all of the reports rolling in of one .user.js engine deleting scripts on import/export (and a very casual look without testing to confirm) I'm a bit leery to just go poking around these days in a "dirty" profile that I should back up more often.

Script injection test nth test:

// ==UserScript==
// @name          oujs - Meta View
// @namespace     https://openuserjs.org/users/Marti
// @description   Adds a script navigation link next to `Source Code` titled `Meta` and opens a phantom url to show the detected metadata
// @copyright     2014+, Marti Martz (https://openuserjs.org/users/Marti)
// @license       CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
// @license       GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// @version       4.4.5
// @icon          https://www.gravatar.com/avatar/7ff58eb098c23feafa72e0b4cd13f396?r=G&s=48&default=identicon

// @homepageURL  https://github.com/Martii/UserScripts/tree/master/src/oujs/Meta%20View
// @homepageURL  https://openuserjs.org/scripts/marti/oujs_-_Meta_View
// @supportURL   https://openuserjs.org/scripts/marti/oujs_-_Meta_View/issues

// @updateURL    https://openuserjs.org/meta/Marti/oujs_-_Meta_View.meta.js
// @downloadURL  https://openuserjs.org/install/Marti/oujs_-_Meta_View.min.user.js

// @include  https://openuserjs.org/scripts/*/*
// @include  http://localhost:8080/scripts/*/*

var x = 10; // *** This breaks script injection and should not ***

// @grant none

// ==/UserScript==

... result FAIL

NOTE Retested... 2nd time... PASS ... bleh... inconsistent results... probably why it's deferred to a later Fx release.


Btw Install button on OUJS still no workie.


New Script "button" with one script already in there copies the source of oujs - Meta View? A little unusual.

erosman commented 5 years ago

space between // @include and //@include It doesn't matter to FireMoneky as it doesn't even look for // .....it looks for @.....

Please note that Regular Expression includes are not supported by the API eg: /^https?://openuserjs\\.org(?::\\d{1,5})?/scripts//

On the option page, when clicking on the script with X after it, it display the script and then.. it has a notification popup with the error plus the the edit area changes colour to show error

error

error2

After removing the RegEx include and enabling the script, the script runs but I dont know what it is supposed to do.

On https://openuserjs.org/scripts/Marti/oujs_-_Meta_View it runs the else on line 556

Martii commented 5 years ago

Never get that. Do get the pink background though.

It doesn't matter to FireMonkey as it doesn't even look for // ..... it looks for @.....

That can be a security risk for starters not to mention a parsing nightmare.... the official spec for metadata blocks are at GM and the original spec of GM Port. Using a proprietary .user.js metadata block is not recommended since it makes it not a .user.js engine. The metadata is critical for parsing and busting that doesn't seem like a wise choice. I would suggest that changes in FireMonkey as it won't be endorsed as a .user.js engine until it does and won't be widely accepted in the community.

Ex.

// ==UserScript==
...
// Let's bury this in a really obnoxious comment and see what can be done.
// So now is the time for all coders to come to the aid of their rights.
// @icon https://www.gravatar.com/avatar/7ff58eb098c23feafa72e0b4cd13f396?r=G&s=48&default=identicon
// This is a regular comment and may show you how you can @require http://example.com/somebadscript.js and your extension will require it based off of the descriptive text explanation.
// Blah, blah, blah, blah... etc. 
// Let's mess with the @icon http://example.com/scaryicon.jpg . Example.com's are ficticious but lets role play. Also what happens with @..... if it's not recognized...haven't tested that part yet but will after the security issue of 
// another............................................................................................................................................................................................................................................................................................ @require http://example.com/anotherbadscript.js
// is addressed.
// @require http://example.com/goodscript.js
...
// ==/UserScript==

(Note: The ellipsis means there is more. This is just a snippet example)

Anyhow... don't want to seem like I'm tilting towards the negative spectrum. The extension has good promise but need a few standardizations on the basics. :smile:


but I dont know what it is supposed to do.

Parses the metadata blocks that we collect (specifically how GM, GM Port, TM, VM, etc. do it)... click on "Meta" on the nav bar.


Ref:

erosman commented 5 years ago

Never get that.

You should get it every time you click on the script with X on the left-side menu to display that script.

That can be a security risk for starters not to mention a parsing nightmare....

I beg to differ. The processing is quite different and are there safeguards. AFA this instance is concerned, it suffices to say that the space after // has no bearing.

Even the naming of .user.js is irrelevant to FireMoneky (at the moment) as it does NOT import scripts the same way as GM (by opening via internet or drag/drop). The import is manual and by user consent.

If a programmer chooses to insert comment that mimics meta-block inside the meta-block, that displays the poor choice of the script writer. Similarly, bad code writing displays the poor choice of the script writer. There is no way for the non-programmer-users to check the code for poor implementation. IMHO, Such scripts should be avoided.

The meta-block is not the place to have comments. That is simply poor and improper practice.

The extension has good promise but need a few standardizations on the basics.

While GM, TM & VM are similar, there are implementation differences that causes some scripts to behave differently (some of these are mentioned in the Help). While adhering to good standards is an improvement, adhering to no-so-good standards are not. Some standards are created by the length of time they have been in use and not by their own merit. ;)

Initially, I created FireMoneky for my own use as I wanted an alternative to the available user JS & CSS managers. I have released it for public use in the hope that some users might find it useful as an alternative, and not in competition with the established extensions.

It goes without saying that upon feedback from the users, FireMonkey will be further improved in future. :)

OpenUserJS/OpenUserJS.org#1330 How GM4 skips over bad/unsupported // @matches now even though it's not Goo standard... this was a major breaking change too from the official spec.

FireMonkey converts some common incompatible patterns automatically. It is not possible to check or convert all such instances. In case of bad-matches, the script does not run and is automatically disabled and a warning is added to the script (as mentioned above). Such scripts are still imparted but do not run until the issue is fixed and then the script is then enabled.

Martii commented 5 years ago

If a programmer chooses to insert comment that mimics meta-block inside the meta-block, that displays the poor choice of the script writer. ... The meta-block is not the place to have comments.

Actually it's excellent, and educated, coding to comment what things are when the url may be abstracted by a QSP/hash/etc. just as line breaks are. Again your opinion however not the communities.

Some standards are created by the length of time

I think that is where this extension fails because you haven't taken the time to consider the security ramifications of poor implementation of the UserScript metadata block. Perhaps you should reevaluate the lack of integrity of this decision?

Even the naming of .user.js is irrelevant to FireMoneky

Much like early Opera used to do... so not a new concept.

it does NOT import scripts the same way as GM (by opening via internet or drag/drop). The import is manual and by user consent.

Again much like early Opera. And you finally answered the lingering observation, implied, question of why it doesn't work with OUJS Install button. Thank you.

It goes without saying that upon feedback from the users, FireMonkey will be further improved in future.

Some people like the chaos theory better. As an individual who has been a systems administrator, engineer, and analyst most of my life I beg to contradict that persona. Clearly you want to open a security hole for the bad actors out there with your non-standardized implementation of the metadata block? Seems like a poor choice if so. Apologies but this is how it looks.

The processing is quite different and are there safeguards.

Saying this and proving it are different animals. I'll reinspect the code for these "safeguards" however if we, as OUJS A.M. and CoOwner, see anything remotely resembling a script that contains your security breach we'll probably have to ban it and quite possibly the Author. I'll have to notify AMO to reinspect your addon as well for this as it's quite easy to obfuscate (and is obfuscation in itself) what is happening buried in a comment after further investigation. I wish you would change your mind and work as a team player on this instead of just what you think is "right your way". The community has a lot of experience should you decide to learn from it. GM was taken off AMO in the early days if you recall (or maybe not... depends on your tenure) for security hacks such as these. Don't let this be a similar repeat... most recently Stylus.

I created FireMoneky for my own use as I wanted an alternative to the available user JS & CSS managers.

Alternatives can be good as long as they are safe. Not following the standards is unsafe and you'll jeopardize the community security.

Initially, I created FireMoneky for my own use as I wanted an alternative to the available user JS & CSS managers.

Perhaps. I've followed you for quite some time even before the visit on my fork so I perceive a little different motivation but I'm also not you... so there is the benefit of the doubt clause. :smile_cat:

and not in competition with the established extensions.

No one, including myself, has stated this. However maturity should come in taking constructive feedback especially when a CERT can be issued against bad extensions. This is part of the reason why Mozilla is changing a lot of the innards to prevent bad acting. Please don't contribute to the destruction of your extension as I said it has promise. Make the wiser choice. Since I'm the primary author/maintainer of GM Port I have no concern about competition or not. In fact I encouraged OUJS to not compete with any other .user.js site and the same goes with GM Port. I gracefully filled a browser deficit with SM so did sizzle from USO. It's not a race to have one sect win. That is immature assumptions and behavior which I do not practice. However improvement is always a goal one step at a time.

FireMonkey converts some common incompatible patterns automatically.

Interesting. Won't go into that one as you are correct there are a lot of variations and also legal implications.

Anyhow... I'll go ahead and close this as you've answered most of the basic questions and improved my understanding of your implementation.

Thanks for the clarifications and understanding.

erosman commented 5 years ago
// ==UserScript==
...
// Let's bury this in a really obnoxious comment and see what can be done.
// So now is the time for all coders to come to the aid of their rights.
// @icon https://www.gravatar.com/avatar/7ff58eb098c23feafa72e0b4cd13f396?r=G&s=48&default=identicon
// This is a regular comment and may show you how you can @require http://example.com/somebadscript.js and your extension will require it based off of the descriptive text explanation.
// Blah, blah, blah, blah... etc. 
// Let's mess with the @icon http://example.com/scaryicon.jpg . Example.com's are ficticious but lets role play. Also what happens with @..... if it's not recognized...haven't tested that part yet but will after the security issue of 
// another............................................................................................................................................................................................................................................................................................ @require http://example.com/anotherbadscript.js
// is addressed.
// @require http://example.com/goodscript.js
...
// ==/UserScript==

Just a note ....

Besides that fact that @require & @icon are not implemented in FireMonkey, the result is for example a match is made in FireMoneky but not in GM

Example:

// ==UserScript==
...
// Let's bury this in a really obnoxious comment and see what can be done.
// Blah, blah, blah @match http://example2.com/*
// ................
// is addressed.
// @match http://example.com/*
...

GM treat this as 1 match and FireMonkey as 2 matches (and they are clearly displayed in the script Info for the user) which is the same as:

// ==UserScript==
...
// Let's bury this in a really obnoxious comment and see what can be done.
// Blah, blah, blah 
// ................
// is addressed.
// @match http://example.com/*
// @match http://example2.com/*
...

Again that is up to users to chose a script and script writer that doesn't attempt to deceive.

Furthermore, in this case, scripts may run on unexpected sites (but there is Info) but so does the result of the wildcard implementation in GM etc i.e. @match *://*.example.*/* which runs on all sorts of unexpected and uninformed sites.

HOWEVER, I will think about ways to prevent the above situation.

Also, FireMonkey supports block metablock which others dont e.g.:

/*
  ....
  @match http://example.com/*
  ....
*/

AFA standards, the standard has never been to include comments in meta-block.

Finally, as per addon's description:

Firemonkey is a totally new extension that can handle both user Scripts and user CSS. While it has similar functions to user script extensions like GreaseMonkey/Tampermonkey/Violentmonkey, and user CSS extensions like Stylish/Stylus, there are differences.

In other words, FireMonkey is not GM or VM or TM and does not aim to be a clone of them either. Therefore, comparison and/or full 100% compatibility is not the criteria.

The included Help explains how FireMonkey works.

Martii commented 5 years ago

Besides that fact that @require & @icon are not implemented in FireMonkey

Those were chosen at random. Pick @name if you wish, or any other key you support, and apply it.

and they are clearly displayed in the script Info for the user

After the fact... not before. Not everyone knows (or sometimes cares) what kind of security issues are present. The responsible thing to do is to educate and put in some basic safeguards. Some put in more than is needed imho (think the other .user.js site) but that is his prerogative within his means.

Again that is up to users to chose a script and script writer that doesn't attempt to deceive.

Might just be a casual comment too describing something which is why the fully documented standard exists and your extension will pick it up incorrectly. You can even have code in between // @keys for example in the UserScript metadata block. Yes I see your consideration edit too.

but so does the result of the wildcard implementation in GM

Well aware of this one. I've banned several UserScripts for being too vague on injection. Some are useful on all sites too. TM/GM Port also has this feature. Been a while since I've tested VM but I think it does too.

AFA standards, the standard has never been to include comments in meta-block.

That's never been the case. Comments and other code have always been accepted on different lines in the UserScript metadata block. E4X is another example that proves it and so are function expressions and the like for restructuring. This goes back to the origin with Aaron which I'm a later addition to that origin. One can even encompass the entire script in the UserScript metadata block if bored. Granted it looks ick but that's one of the reason why oujs - Meta View was created... in case it's so terribly (imho) abstracted/obfuscated for even newer technologies and methodologies. I ran into one that mirrors node syntax in UserScripts... that threw me for a loop until I asked the Author what was going on... he helped me understand and I helped that Author out too with the build routine to not violate Copyright.

Also, FireMonkey supports block metablock which others dont

Interesting... that is another parsing nightmare (not yours necessarily... but everyone else who may consider implementing and hosting your new type).

Therefore, comparison and/or full 100% compatibility is not the criteria.

You actively sought out for my feedback... there it is. Even if I had no knowledge of UserScripts I'd still come to these same security concerns of accidental or intentional script injection or alteration.

If you want to try to make a spin-off like JetPack used to be you are always welcome to. :) Perhaps it will catch on... perhaps not. You know my 2 cents on this particular security issue. I do like less extensions but at the same time not at the expense of my default understanding of security and privacy.

erosman commented 5 years ago

Thank you for the feedback which will be taken into consideration.

erosman commented 5 years ago

Just to let you know, I have updated the code to prevent the unwanted processing of // Blah, blah, blah @match http://example2.com/* It will be in v1.6