From 140a7924a1872b78da7164290c3f6e461b8ba038 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Thu, 24 Apr 2014 21:16:12 -0700 Subject: [PATCH 01/22] 1.5a.rev1 Starting 1.5a3 - goal is to allow install of uncommitted file (the file you are currently editing) -copy paste from yajd commit #61: https://github.com/yajd/GitHubExtIns/commit/181247066db0f3ad79a6ea2493ea7b2648b8ac8c --- bootstrap.js | 407 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 351 insertions(+), 56 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 3fa21dc..ac52ebe 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -16,6 +16,11 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/devtools/Console.jsm"); +Cu.import("resource://gre/modules/osfile.jsm"); +const { TextEncoder, TextDecoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {}); + +var TEncoder; function LOG(m) (m = addon.name + ' Message @ ' + (new Date()).toISOString() + "\n> " + m, @@ -74,6 +79,11 @@ function onClickHanlder(ev) { "Don't click me more than once, reload the page to retry."); return; } + + if (this.classList.contains('disabled')) { + console.log('button is disabled so exit'); + return; + } this.setAttribute(addon.tag,1); this.className += ' danger disabled'; @@ -81,7 +91,7 @@ function onClickHanlder(ev) { l = this.lastChild, f = this.firstChild; l.textContent = ' Installing...'; - f.className = f.className.replace('plus','hourglass'); + f.className = f.className.replace(/(?:plus|check)/,'hourglass'); d.body.appendChild(d.createElement('style')).textContent = '@keyframes ' +addon.tag+'{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}'; f.style.animation = addon.tag + ' 3s infinite linear'; @@ -106,12 +116,29 @@ function onClickHanlder(ev) { .createInstance(Ci.nsIZipWriter); let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + console.log('pre zip open'); + console.log('this.getAttribute(path) = ', this.getAttribute('path')); + + zipReader.open(nFile); zipWriter.open(oFile, 0x2c); + + console.log('zip opened'); + let p = (this.getAttribute('path') || "*/"), m = zipReader.findEntries(p + "*"); p = p.substr(2); + + if (this.hasAttribute('filepath')) { + var fileName = this.getAttribute('filepath'); + var useUncommitedFilePath = this.getAttribute('filepath').replace(this.getAttribute('path'), ''); //relative to path, because thats what is getting written to xpi + fileName = fileName.substr(fileName.lastIndexOf('/')+1); + console.log('the filename is = ', fileName); + + var tmpFileOfUncommitedFile = new FileUtils.File(oFile.parent.path + '\\' + fileName) + } + while(m.hasMore()) { let f = m.getNext(), e = zipReader.getEntry(f); @@ -127,78 +154,155 @@ function onClickHanlder(ev) { zipWriter.addEntryDirectory(n,e.lastModifiedTime,!1); } else { - - zipWriter.addEntryStream(n, e.lastModifiedTime, - Ci.nsIZipWriter.COMPRESSION_FASTEST, - zipReader.getInputStream(f), !1); + if (useUncommitedFilePath && n == useUncommitedFilePath) { + console.log('was writing to zip n, n =', n); + console.log('but we are in edit page of this so dont add this file from zip, we will create file out of that and add it after this while loop'); + } else { + zipWriter.addEntryStream(n, e.lastModifiedTime, + Ci.nsIZipWriter.COMPRESSION_FASTEST, + zipReader.getInputStream(f), !1); + } } } - zipReader.close(); - zipWriter.close(); - - AddonManager.getInstallForFile(oFile,aInstall => { - let done = (aMsg,aAddon) => { - let c = 'check'; - if(typeof aMsg === 'number') { - l.textContent = 'Error ' + aMsg; - aMsg = 'Installation failed ('+aMsg+')'; - c = 'alert'; - } else { - l.textContent = 'Succeed!'; - this.className = this.className.replace('danger',''); - } - f.style.animation = null; - f.className = f.className.replace('hourglass',c); - iNotify(aAddon, aMsg, aResult => { - oFile.remove(!1); + var btn = this; + + var postZipWrite = function() { + console.log('zip closed'); + + zipReader.close(); + zipWriter.close(); + + AddonManager.getInstallForFile(oFile,aInstall => { + let done = (aMsg,aAddon) => { + let c = 'check'; + if(typeof aMsg === 'number') { + l.textContent = 'Error ' + aMsg; + aMsg = 'Installation failed ('+aMsg+')'; + c = 'alert'; + } else { + if (!btn.hasAttribute('filepath')) { + l.textContent = 'Succeed!'; + btn.className = btn.className.replace('danger',''); + } else { + //it is uncommited file install so allow reclicking of button + l.textContent = 'Installed with Uncommitted File - Reinstall'; + btn.classList.remove('danger'); + btn.classList.remove('disabled'); + btn.removeAttribute(addon.tag); //so allows reinstall + } + } + f.style.animation = null; + f.className = f.className.replace('hourglass',c); + iNotify(aAddon, aMsg, aResult => { + //oFile.remove(!1); + var promiseOFileRemove = OS.File.remove(oFile.path); + promiseOFileRemove.then( + function onsuc() { + console.log('succesfully deleted ofile', oFile.path); + }, + function(aRejectReason) { + console.error('promiseRemove ofile failed = ', aRejectReason); + } + ); - if(aResult !== null && aAddon && aAddon.pendingOperations) { - let m = aAddon.name + ' requires restart.\n\n' - + 'Would you like to restart ' - + Services.appinfo.name + ' now?'; + if(aResult !== null && aAddon && aAddon.pendingOperations) { + let m = aAddon.name + ' requires restart.\n\n' + + 'Would you like to restart ' + + Services.appinfo.name + ' now?'; - m = Services.prompt.confirmEx(null, - addon.name,m,1027,0,0,0,null,{}); + m = Services.prompt.confirmEx(null, + addon.name,m,1027,0,0,0,null,{}); - if(!m) { - let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] - .createInstance(Ci.nsISupportsPRBool); + if(!m) { + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); - Services.obs.notifyObservers(cancelQuit, - "quit-application-requested", null); + Services.obs.notifyObservers(cancelQuit, + "quit-application-requested", null); - if(!cancelQuit.data) { - Services.obs.notifyObservers(null, - "quit-application-granted", null); + if(!cancelQuit.data) { + Services.obs.notifyObservers(null, + "quit-application-granted", null); - Services.startup.quit( - Ci.nsIAppStartup.eAttemptQuit | - Ci.nsIAppStartup.eRestart - ); + Services.startup.quit( + Ci.nsIAppStartup.eAttemptQuit | + Ci.nsIAppStartup.eRestart + ); + } } } + }); + }; + + aInstall.addListener({ + onInstallFailed : function(aInstall) { + aInstall.removeListener(this); + + done(aInstall.error); + }, + onInstallEnded : function(aInstall,aAddon) { + aInstall.removeListener(this); + + done(aAddon.name + ' ' + aAddon.version + + ' has been installed successfully.',aAddon); } }); - }; - - aInstall.addListener({ - onInstallFailed : function(aInstall) { - aInstall.removeListener(this); + aInstall.install(); + }); - done(aInstall.error); + //nFile.remove(!1); //should probably change to use OS.File so should be OS.File.remove(nFile.path); + var promiseRemove = OS.File.remove(nFile.path); + promiseRemove.then( + function onsuc() { + console.log('succesfully deleted nfile', nFile.path); }, - onInstallEnded : function(aInstall,aAddon) { - aInstall.removeListener(this); - - done(aAddon.name + ' ' + aAddon.version - + ' has been installed successfully.',aAddon); + function(aRejectReason) { + console.error('promiseRemove nfile failed = ', aRejectReason); } - }); - aInstall.install(); - }); + ); + }; + var postZipWriteBinded = postZipWrite.bind(this); + + if (this.hasAttribute('filepath')) { + console.log('now creating file out of file on edit page and then will add it in'); + if (!TEncoder) { + TEncoder = new TextEncoder(); // This encoder can be reused for several writes + } + let BufferArray = TEncoder.encode(this.ownerDocument.querySelector('#blob_contents').value); // Convert the text to an array + let promiseCreateUncommitedFile = OS.File.writeAtomic(tmpFileOfUncommitedFile.path, BufferArray, { + tmpPath: tmpFileOfUncommitedFile.path + '.tmp' + }); + promiseCreateUncommitedFile.then( + function() { + console.log('uncommited file succesfully created so now adding this file to zip then doing postZipWriteBinded'); + zipWriter.addEntryFile(useUncommitedFilePath, + Ci.nsIZipWriter.COMPRESSION_FASTEST, + tmpFileOfUncommitedFile, !1); + + + var promiseRemoveUncommitedFile = OS.File.remove(tmpFileOfUncommitedFile.path); + promiseRemoveUncommitedFile.then( + function() { + console.log('succesfully deleted file', tmpFileOfUncommitedFile.path); + }, + function(aRejectReason) { + console.warn('removing uncommited file from tmp failed = ', aRejectReason); + } + ); + + postZipWriteBinded(); + }, + function(aRejectReason) { + console.error('creating file of uncommited file failed'); + } + ); + } else { + console.log('doing postZipWriteBinded right away as no need for promise'); + postZipWriteBinded(); + } + - nFile.remove(!1); } }); }); @@ -242,9 +346,13 @@ function addButton(n,u) { n.firstChild.style.verticalAlign = 'baseline'; } } + + return n; } function onPageLoad(doc) { + var editForm = doc.querySelector('.js-blob-form.js-blob-edit-form'); + if(doc.location.pathname.replace(/\/[^/]+$/,'').substr(-4) === 'pull') { // Based on work by Jerone: https://github.com/jerone/UserScripts @@ -292,6 +400,193 @@ function onPageLoad(doc) { } } } + else if (editForm && editForm.hasAttribute('action')) { + //add disabled button saying it is checking parent dirs for install.rdf + var filePath = editForm.getAttribute('action'); //'https://github.com/yajd/XPICompiler/tree-save/master/release/bootstrap.js'; + /* + //start searching parent dirs till find intall.rdf, first install.rdf it finds it will install that and edit this file into it + var determineAndloadDir = function(argFilePath) { + if (argFilePath[0] == '/') { + var spliceOrigin = true; + argFilePath = argFilePath.slice(1); + } + var pathSplit = argFilePath.split('/'); + if (spliceOrigin) { + pathSplit.splice(0, 0, doc.defaultView.location.origin); + } + dirPath = pathSplit.slice(0, pathSplit.length - 1).join('/'); + var isRootDir = false; + if (pathSplit[pathSplit.length - 2] == 'master') { + //this is root dir so after loadDir, if still no rdf then give up + isRootDir = true; + } + loadDir(dirPath, isRootDir); + } + + var loadDir = function(argDirPath, argIsRootDir) { + var cb = function(responseText) { + lookForInstallRdfAndMakeButton(responseText, argDirPath, argIsRootDir); + }; + xhr(argDirPath, cb); + } + + var lookForInstallRdfAndMakeButton = function(argResponseText, argDirPath, argIsRootDir) { + //if src has install.rdf then do addButton else if !argIsRootDirPath then determineAndloadDir(argDirPath) ELSE give up + console.log(argResponseText); + } + + determineAndloadDir(filePath); + //start searching for rdf + */ + let c = 7, n, z; + console.log('looking for cloning node'); + while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); + + if(n && n.textContent.trim() === 'Download ZIP') { + console.log('cloning node found'); + c = doc.querySelector('div.only-with-full-nav'); + + if(!c || doc.defaultView.getComputedStyle(c).getPropertyValue('display') == 'block') { + console.log('doing addButton'); + addButton(n); + console.log('done adding button'); + } else { + console.log('c not found'); + z = n; + n = 0; + } + } + + if(!n) { + console.log('n not found'); + console.log('so looking for breadcrumb'); + n = doc.querySelector('div.breadcrumb'); + n = n && n.firstElementChild; + + if( n ) { + console.log('done adding button breadcrumb'); + var btn = addButton(n,z); + //btn.setAttribute('path', ); + btn.className += ' danger disabled' + var l = btn.lastChild; + var f = btn.firstChild; + l.textContent = ' Checking if Installable...'; + f.className = f.className.replace('plus','hourglass'); + + var breadcrumbs = doc.querySelectorAll('span[itemtype*=Breadcrumb]'); + var breads = ['*']; + for (var i=1; i { + let iStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"] + .createInstance(Ci.nsIArrayBufferInputStream); + + iStream.setData(data,0,data.byteLength); + + let nFile = FileUtils.getFile("TmpD", [Math.random()]) + oStream = FileUtils.openSafeFileOutputStream(nFile); + + NetUtil.asyncCopy(iStream, oStream, aStatus => { + if(!Components.isSuccessCode(aStatus)) { + Services.prompt.alert(null,addon.name, + 'Error while checking if installable error was ' +aStatus+ ' writing to ' +nFile.path); + } else { + let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] + .createInstance(Ci.nsIZipReader); + + let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + console.log('pre zip open'); + console.log('btn.getAttribute(path) = ', btn.getAttribute('path')); + //*/ //*/release/ + + + zipReader.open(nFile); + + console.log('zip opened'); + + var entries = zipReader.findEntries(null); + while(entries.hasMore()) { + let entryFileName = entries.getNext(); + /* + string + */ + let entryZipFile = zipReader.getEntry(entryFileName); + /* + CRC32:1312936884 + QueryInterface:QueryInterface() + compression:0 + isDirectory:false + isSynthetic:false + lastModifiedTime:1398298243000000 + permissions:256 + realSize:6547 + size:6547 + __proto__:Object + */ + console.info(entryFileName, typeof(entryFileName), entryZipFile); + } + + + for (var i=0; i Date: Thu, 24 Apr 2014 21:18:08 -0700 Subject: [PATCH 02/22] 1.5a3.rev2 -Copy paste of yajd commit #62 (https://github.com/yajd/GitHubExtIns/blob/0a677ff88f1a361ded052beb068016be462a1c95/bootstrap.js) -Cut out the extraneous code running when adding button to editable page -Cleaned for PullRequest (PR) --- bootstrap.js | 161 +++++---------------------------------------------- 1 file changed, 15 insertions(+), 146 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index ac52ebe..4fbec6d 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -16,9 +16,8 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/devtools/Console.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); -const { TextEncoder, TextDecoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {}); +const { TextEncoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {}); var TEncoder; @@ -80,8 +79,7 @@ function onClickHanlder(ev) { return; } - if (this.classList.contains('disabled')) { - console.log('button is disabled so exit'); + if (this.classList.contains('disabled')) { //needed for when checking if editable file is installable return; } @@ -115,17 +113,11 @@ function onClickHanlder(ev) { zipWriter = Cc["@mozilla.org/zipwriter;1"] .createInstance(Ci.nsIZipWriter); - let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); - console.log('pre zip open'); - console.log('this.getAttribute(path) = ', this.getAttribute('path')); - + let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); zipReader.open(nFile); zipWriter.open(oFile, 0x2c); - console.log('zip opened'); - - let p = (this.getAttribute('path') || "*/"), m = zipReader.findEntries(p + "*"); p = p.substr(2); @@ -133,9 +125,7 @@ function onClickHanlder(ev) { if (this.hasAttribute('filepath')) { var fileName = this.getAttribute('filepath'); var useUncommitedFilePath = this.getAttribute('filepath').replace(this.getAttribute('path'), ''); //relative to path, because thats what is getting written to xpi - fileName = fileName.substr(fileName.lastIndexOf('/')+1); - console.log('the filename is = ', fileName); - + fileName = fileName.substr(fileName.lastIndexOf('/')+1); var tmpFileOfUncommitedFile = new FileUtils.File(oFile.parent.path + '\\' + fileName) } @@ -155,8 +145,7 @@ function onClickHanlder(ev) { } else { if (useUncommitedFilePath && n == useUncommitedFilePath) { - console.log('was writing to zip n, n =', n); - console.log('but we are in edit page of this so dont add this file from zip, we will create file out of that and add it after this while loop'); + //skip adding file } else { zipWriter.addEntryStream(n, e.lastModifiedTime, Ci.nsIZipWriter.COMPRESSION_FASTEST, @@ -168,7 +157,6 @@ function onClickHanlder(ev) { var btn = this; var postZipWrite = function() { - console.log('zip closed'); zipReader.close(); zipWriter.close(); @@ -195,16 +183,7 @@ function onClickHanlder(ev) { f.style.animation = null; f.className = f.className.replace('hourglass',c); iNotify(aAddon, aMsg, aResult => { - //oFile.remove(!1); - var promiseOFileRemove = OS.File.remove(oFile.path); - promiseOFileRemove.then( - function onsuc() { - console.log('succesfully deleted ofile', oFile.path); - }, - function(aRejectReason) { - console.error('promiseRemove ofile failed = ', aRejectReason); - } - ); + OS.File.remove(oFile.path); if(aResult !== null && aAddon && aAddon.pendingOperations) { let m = aAddon.name + ' requires restart.\n\n' @@ -251,21 +230,11 @@ function onClickHanlder(ev) { aInstall.install(); }); - //nFile.remove(!1); //should probably change to use OS.File so should be OS.File.remove(nFile.path); - var promiseRemove = OS.File.remove(nFile.path); - promiseRemove.then( - function onsuc() { - console.log('succesfully deleted nfile', nFile.path); - }, - function(aRejectReason) { - console.error('promiseRemove nfile failed = ', aRejectReason); - } - ); + OS.File.remove(nFile.path); }; var postZipWriteBinded = postZipWrite.bind(this); if (this.hasAttribute('filepath')) { - console.log('now creating file out of file on edit page and then will add it in'); if (!TEncoder) { TEncoder = new TextEncoder(); // This encoder can be reused for several writes } @@ -275,30 +244,15 @@ function onClickHanlder(ev) { }); promiseCreateUncommitedFile.then( function() { - console.log('uncommited file succesfully created so now adding this file to zip then doing postZipWriteBinded'); zipWriter.addEntryFile(useUncommitedFilePath, Ci.nsIZipWriter.COMPRESSION_FASTEST, tmpFileOfUncommitedFile, !1); - - var promiseRemoveUncommitedFile = OS.File.remove(tmpFileOfUncommitedFile.path); - promiseRemoveUncommitedFile.then( - function() { - console.log('succesfully deleted file', tmpFileOfUncommitedFile.path); - }, - function(aRejectReason) { - console.warn('removing uncommited file from tmp failed = ', aRejectReason); - } - ); - + OS.File.remove(tmpFileOfUncommitedFile.path); postZipWriteBinded(); - }, - function(aRejectReason) { - console.error('creating file of uncommited file failed'); } ); } else { - console.log('doing postZipWriteBinded right away as no need for promise'); postZipWriteBinded(); } @@ -401,72 +355,22 @@ function onPageLoad(doc) { } } else if (editForm && editForm.hasAttribute('action')) { - //add disabled button saying it is checking parent dirs for install.rdf - var filePath = editForm.getAttribute('action'); //'https://github.com/yajd/XPICompiler/tree-save/master/release/bootstrap.js'; - /* - //start searching parent dirs till find intall.rdf, first install.rdf it finds it will install that and edit this file into it - var determineAndloadDir = function(argFilePath) { - if (argFilePath[0] == '/') { - var spliceOrigin = true; - argFilePath = argFilePath.slice(1); - } - var pathSplit = argFilePath.split('/'); - if (spliceOrigin) { - pathSplit.splice(0, 0, doc.defaultView.location.origin); - } - dirPath = pathSplit.slice(0, pathSplit.length - 1).join('/'); - var isRootDir = false; - if (pathSplit[pathSplit.length - 2] == 'master') { - //this is root dir so after loadDir, if still no rdf then give up - isRootDir = true; - } - loadDir(dirPath, isRootDir); - } - - var loadDir = function(argDirPath, argIsRootDir) { - var cb = function(responseText) { - lookForInstallRdfAndMakeButton(responseText, argDirPath, argIsRootDir); - }; - xhr(argDirPath, cb); - } - - var lookForInstallRdfAndMakeButton = function(argResponseText, argDirPath, argIsRootDir) { - //if src has install.rdf then do addButton else if !argIsRootDirPath then determineAndloadDir(argDirPath) ELSE give up - console.log(argResponseText); - } - - determineAndloadDir(filePath); - //start searching for rdf - */ + var filePath = editForm.getAttribute('action'); let c = 7, n, z; - console.log('looking for cloning node'); while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); if(n && n.textContent.trim() === 'Download ZIP') { - console.log('cloning node found'); c = doc.querySelector('div.only-with-full-nav'); - - if(!c || doc.defaultView.getComputedStyle(c).getPropertyValue('display') == 'block') { - console.log('doing addButton'); - addButton(n); - console.log('done adding button'); - } else { - console.log('c not found'); - z = n; - n = 0; - } + z = n; + n = 0; } if(!n) { - console.log('n not found'); - console.log('so looking for breadcrumb'); n = doc.querySelector('div.breadcrumb'); n = n && n.firstElementChild; if( n ) { - console.log('done adding button breadcrumb'); var btn = addButton(n,z); - //btn.setAttribute('path', ); btn.className += ' danger disabled' var l = btn.lastChild; var f = btn.firstChild; @@ -478,17 +382,13 @@ function onPageLoad(doc) { for (var i=1; i Date: Fri, 4 Jul 2014 18:27:23 -0700 Subject: [PATCH 03/22] 1.5a3.rev3 bootstrap.js * Implemented discussion from here: https://github.com/diegocr/GitHubExtIns/pull/10/files * Did not address the using repeated code block --- bootstrap.js | 186 +++++++++++++++++++++------------------------------ 1 file changed, 77 insertions(+), 109 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 4fbec6d..1ba9ed5 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -6,6 +6,9 @@ * * Contributor(s): * Diego Casorran (Original Author) + * Jerone + * Zulkarnain K. + * Noitidart (Authored Contirubtion: "Install from Edit Page without Committing") * * ***** END LICENSE BLOCK ***** */ @@ -16,10 +19,6 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -const { TextEncoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {}); - -var TEncoder; function LOG(m) (m = addon.name + ' Message @ ' + (new Date()).toISOString() + "\n> " + m, @@ -113,7 +112,7 @@ function onClickHanlder(ev) { zipWriter = Cc["@mozilla.org/zipwriter;1"] .createInstance(Ci.nsIZipWriter); - let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); zipReader.open(nFile); zipWriter.open(oFile, 0x2c); @@ -125,8 +124,6 @@ function onClickHanlder(ev) { if (this.hasAttribute('filepath')) { var fileName = this.getAttribute('filepath'); var useUncommitedFilePath = this.getAttribute('filepath').replace(this.getAttribute('path'), ''); //relative to path, because thats what is getting written to xpi - fileName = fileName.substr(fileName.lastIndexOf('/')+1); - var tmpFileOfUncommitedFile = new FileUtils.File(oFile.parent.path + '\\' + fileName) } while(m.hasMore()) { @@ -145,7 +142,9 @@ function onClickHanlder(ev) { } else { if (useUncommitedFilePath && n == useUncommitedFilePath) { - //skip adding file + let is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); + is.data = this.ownerDocument.querySelector('#blob_contents').value; + zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); } else { zipWriter.addEntryStream(n, e.lastModifiedTime, Ci.nsIZipWriter.COMPRESSION_FASTEST, @@ -154,108 +153,78 @@ function onClickHanlder(ev) { } } - var btn = this; - - var postZipWrite = function() { - - zipReader.close(); - zipWriter.close(); - - AddonManager.getInstallForFile(oFile,aInstall => { - let done = (aMsg,aAddon) => { - let c = 'check'; - if(typeof aMsg === 'number') { - l.textContent = 'Error ' + aMsg; - aMsg = 'Installation failed ('+aMsg+')'; - c = 'alert'; + zipReader.close(); + zipWriter.close(); + + AddonManager.getInstallForFile(oFile,aInstall => { + let done = (aMsg,aAddon) => { + let c = 'check'; + if(typeof aMsg === 'number') { + l.textContent = 'Error ' + aMsg; + aMsg = 'Installation failed ('+aMsg+')'; + c = 'alert'; + } else { + if (!this.hasAttribute('filepath')) { + l.textContent = 'Succeed!'; + this.className = this.className.replace('danger',''); } else { - if (!btn.hasAttribute('filepath')) { - l.textContent = 'Succeed!'; - btn.className = btn.className.replace('danger',''); - } else { - //it is uncommited file install so allow reclicking of button - l.textContent = 'Installed with Uncommitted File - Reinstall'; - btn.classList.remove('danger'); - btn.classList.remove('disabled'); - btn.removeAttribute(addon.tag); //so allows reinstall - } + //it is uncommited file install so allow reclicking of button + l.textContent = 'Installed with Uncommitted File - Reinstall'; + this.classList.remove('danger'); + this.classList.remove('disabled'); + this.removeAttribute(addon.tag); //so allows reinstall } - f.style.animation = null; - f.className = f.className.replace('hourglass',c); - iNotify(aAddon, aMsg, aResult => { - OS.File.remove(oFile.path); - - if(aResult !== null && aAddon && aAddon.pendingOperations) { - let m = aAddon.name + ' requires restart.\n\n' - + 'Would you like to restart ' - + Services.appinfo.name + ' now?'; - - m = Services.prompt.confirmEx(null, - addon.name,m,1027,0,0,0,null,{}); - - if(!m) { - let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] - .createInstance(Ci.nsISupportsPRBool); - - Services.obs.notifyObservers(cancelQuit, - "quit-application-requested", null); - - if(!cancelQuit.data) { - Services.obs.notifyObservers(null, - "quit-application-granted", null); - - Services.startup.quit( - Ci.nsIAppStartup.eAttemptQuit | - Ci.nsIAppStartup.eRestart - ); - } + } + f.style.animation = null; + f.className = f.className.replace('hourglass',c); + iNotify(aAddon, aMsg, aResult => { + oFile.remove(!1); + if(aResult !== null && aAddon && aAddon.pendingOperations) { + let m = aAddon.name + ' requires restart.\n\n' + + 'Would you like to restart ' + + Services.appinfo.name + ' now?'; + + m = Services.prompt.confirmEx(null, + addon.name,m,1027,0,0,0,null,{}); + + if(!m) { + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); + + Services.obs.notifyObservers(cancelQuit, + "quit-application-requested", null); + + if(!cancelQuit.data) { + Services.obs.notifyObservers(null, + "quit-application-granted", null); + + Services.startup.quit( + Ci.nsIAppStartup.eAttemptQuit | + Ci.nsIAppStartup.eRestart + ); } } - }); - }; - - aInstall.addListener({ - onInstallFailed : function(aInstall) { - aInstall.removeListener(this); - - done(aInstall.error); - }, - onInstallEnded : function(aInstall,aAddon) { - aInstall.removeListener(this); - - done(aAddon.name + ' ' + aAddon.version - + ' has been installed successfully.',aAddon); } }); - aInstall.install(); + }; + + aInstall.addListener({ + onInstallFailed : function(aInstall) { + aInstall.removeListener(this); + + done(aInstall.error); + }, + onInstallEnded : function(aInstall,aAddon) { + aInstall.removeListener(this); + + done(aAddon.name + ' ' + aAddon.version + + ' has been installed successfully.',aAddon); + } }); - - OS.File.remove(nFile.path); - }; - var postZipWriteBinded = postZipWrite.bind(this); - - if (this.hasAttribute('filepath')) { - if (!TEncoder) { - TEncoder = new TextEncoder(); // This encoder can be reused for several writes - } - let BufferArray = TEncoder.encode(this.ownerDocument.querySelector('#blob_contents').value); // Convert the text to an array - let promiseCreateUncommitedFile = OS.File.writeAtomic(tmpFileOfUncommitedFile.path, BufferArray, { - tmpPath: tmpFileOfUncommitedFile.path + '.tmp' - }); - promiseCreateUncommitedFile.then( - function() { - zipWriter.addEntryFile(useUncommitedFilePath, - Ci.nsIZipWriter.COMPRESSION_FASTEST, - tmpFileOfUncommitedFile, !1); - - OS.File.remove(tmpFileOfUncommitedFile.path); - postZipWriteBinded(); - } - ); - } else { - postZipWriteBinded(); - } - + aInstall.install(); + }); + + nFile.remove(!1); } }); @@ -305,7 +274,7 @@ function addButton(n,u) { } function onPageLoad(doc) { - var editForm = doc.querySelector('.js-blob-form.js-blob-edit-form'); + if(doc.location.pathname.replace(/\/[^/]+$/,'').substr(-4) === 'pull') { // Based on work by Jerone: https://github.com/jerone/UserScripts @@ -354,7 +323,8 @@ function onPageLoad(doc) { } } } - else if (editForm && editForm.hasAttribute('action')) { + else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && doc.querySelector('.js-blob-form.js-blob-edit-form') && doc.querySelector('.js-blob-form.js-blob-edit-form').hasAttribute('action')) { + var editForm = doc.querySelector('.js-blob-form.js-blob-edit-form'); var filePath = editForm.getAttribute('action'); let c = 7, n, z; while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); @@ -424,8 +394,7 @@ function onPageLoad(doc) { let entryFileName = entries.getNext(); let entryZipFile = zipReader.getEntry(entryFileName); } - - + for (var i=0; i Date: Fri, 4 Jul 2014 18:34:18 -0700 Subject: [PATCH 04/22] 1.5a3.rev4 bootstrap.js * Forgot to mention that in previous commit, in the top comment block I added all the contributors install.rdf * Up revved to 1.5a3 * Increase max FF version to 31.* as thats what I tested it in * Added myself to the contributor tag * Added emails for Jerone and Zulkarnain K. and myself to match with diego --- install.rdf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install.rdf b/install.rdf index 8ec88f5..95396b4 100644 --- a/install.rdf +++ b/install.rdf @@ -4,18 +4,19 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5a2 + 1.5a3 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone Zulkarnain K. + Noitidart <noitidart@gmail.com> true {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 22.0 - 27.* + 31.* @@ -43,4 +44,4 @@ - \ No newline at end of file + From 8b04bc1b7f898d4b250227c2fb30cdfbe004ce00 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Fri, 14 Nov 2014 22:44:02 -0800 Subject: [PATCH 05/22] 1.5a3.rev5 github made a chance so had to change selector to get form properly, this here is untested but it should work --- bootstrap.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 1ba9ed5..40e2bcb 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -323,8 +323,8 @@ function onPageLoad(doc) { } } } - else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && doc.querySelector('.js-blob-form.js-blob-edit-form') && doc.querySelector('.js-blob-form.js-blob-edit-form').hasAttribute('action')) { - var editForm = doc.querySelector('.js-blob-form.js-blob-edit-form'); + else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && doc.querySelector('.js-blob-form') && doc.querySelector('.js-blob-form').hasAttribute('action')) { + var editForm = doc.querySelector('.js-blob-form'); var filePath = editForm.getAttribute('action'); let c = 7, n, z; while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); From 7678bb2f0a4a88f77b3b486a56325312abe592f4 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Fri, 14 Nov 2014 22:44:44 -0800 Subject: [PATCH 06/22] 1.5a4 up reved to a4 --- install.rdf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.rdf b/install.rdf index 95396b4..9029db7 100644 --- a/install.rdf +++ b/install.rdf @@ -4,7 +4,7 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5a3 + 1.5a4 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone From 7573f523612297db7e347ea4f68126ef98b322e1 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Sat, 15 Nov 2014 00:18:36 -0800 Subject: [PATCH 07/22] 1.5a4.rev2 made it so it avoids the triple `doc.querySelector('.js-blob-form)`. now only does it once and holds it in `myElseIfVar`. see here for more reasoning: http://stackoverflow.com/a/26943768/1828637 --- bootstrap.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 40e2bcb..546640b 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -275,7 +275,7 @@ function addButton(n,u) { function onPageLoad(doc) { - + var myElseIfVar; if(doc.location.pathname.replace(/\/[^/]+$/,'').substr(-4) === 'pull') { // Based on work by Jerone: https://github.com/jerone/UserScripts @@ -323,8 +323,8 @@ function onPageLoad(doc) { } } } - else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && doc.querySelector('.js-blob-form') && doc.querySelector('.js-blob-form').hasAttribute('action')) { - var editForm = doc.querySelector('.js-blob-form'); + else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && (myElseIfVar = doc.querySelector('.js-blob-form')) && myElseIfVar.hasAttribute('action')) { + var editForm = myElseIfVar; var filePath = editForm.getAttribute('action'); let c = 7, n, z; while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); From 6e35521ace2744f6eea9031fbb6c12d02e54a1fb Mon Sep 17 00:00:00 2001 From: Noitidart Date: Mon, 16 Mar 2015 21:14:24 -0700 Subject: [PATCH 08/22] 1.5a4.rev3 GitHub changed their selectors a bit on the filename, so added old and new way, in case they revert --- bootstrap.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index 546640b..3fd0004 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -362,7 +362,8 @@ function onPageLoad(doc) { btn.setAttribute('path', breads.join('/') + '/'); - var filename = doc.querySelector('input.filename').getAttribute('value'); //dont use .value here otherwise it gets renamed + var filenameEl = (doc.querySelector('input.filename') || doc.querySelector('.js-blob-filename')); + var filename = filenameEl.getAttribute('value'); //dont use .value here otherwise it gets renamed breads.push(filename); btn.setAttribute('filepath', breads.join('/')); From 8cf13f46d4be905d0cd02b5c1e129017be9de78d Mon Sep 17 00:00:00 2001 From: Noitidart Date: Sun, 5 Apr 2015 11:11:33 -0700 Subject: [PATCH 09/22] 1.5a4.rev4 github changed their site, so add button wasnt working on main page. this fixes it --- bootstrap.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 3fd0004..defc2fc 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -298,27 +298,33 @@ function onPageLoad(doc) { } else if([].some.call(doc.querySelectorAll('table.files > tbody > tr > td.content'), (n) => 'install.rdf' === n.textContent.trim())) { - +console.error('here'); let c = 7, n, z; + n = doc.querySelector('a.sidebar-button[href*=".zip"]'); + console.error('with just n, n is:', n); + addButton(n); + /* while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); if(n && n.textContent.trim() === 'Download ZIP') { c = doc.querySelector('div.only-with-full-nav'); if(!c || doc.defaultView.getComputedStyle(c).getPropertyValue('display') == 'block') { + console.error('with just n, n is:', n); addButton(n); } else { z = n; n = 0; } } + */ if(!n) { n = doc.querySelector('div.file-navigation'); n = n && n.firstElementChild; if( n ) { - + console.error('n and z, n:', n, 'z:', z); addButton(n,z); } } From 0690c2906f7182e63711a814fb4f99827ec72425 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Mon, 6 Apr 2015 09:58:59 -0700 Subject: [PATCH 10/22] Update bootstrap.js trying out @Jerone's recommendation of changing minibutton to btn.btn-sm from here: https://github.com/diegocr/GitHubExtIns/pull/10/files#r27792537 --- bootstrap.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index defc2fc..1665c8e 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -265,7 +265,7 @@ function addButton(n,u) { if(typeof u !== 'object') { n.className += ' button primary pseudo-class-active'; } else { - n.className = 'minibutton pseudo-class-active'; + n.className = 'btn btn-sm minibutton pseudo-class-active'; n.firstChild.style.verticalAlign = 'baseline'; } } @@ -301,10 +301,7 @@ function onPageLoad(doc) { console.error('here'); let c = 7, n, z; n = doc.querySelector('a.sidebar-button[href*=".zip"]'); - console.error('with just n, n is:', n); - addButton(n); - /* - while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); + while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+'),a.btn.btn-sm:nth-child('+c+')'))); if(n && n.textContent.trim() === 'Download ZIP') { c = doc.querySelector('div.only-with-full-nav'); @@ -317,7 +314,6 @@ console.error('here'); n = 0; } } - */ if(!n) { n = doc.querySelector('div.file-navigation'); @@ -333,7 +329,7 @@ console.error('here'); var editForm = myElseIfVar; var filePath = editForm.getAttribute('action'); let c = 7, n, z; - while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+')'))); + while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+'),a.btn.btn-sm:nth-child('+c+')'))); if(n && n.textContent.trim() === 'Download ZIP') { c = doc.querySelector('div.only-with-full-nav'); From ce3205e958a9d590a04f728f18f5dc1535dfd9bd Mon Sep 17 00:00:00 2001 From: Noitidart Date: Mon, 6 Apr 2015 10:41:58 -0700 Subject: [PATCH 11/22] Update bootstrap.js Removed console.log messages that I accidentally left in --- bootstrap.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 1665c8e..ca4f052 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -298,7 +298,6 @@ function onPageLoad(doc) { } else if([].some.call(doc.querySelectorAll('table.files > tbody > tr > td.content'), (n) => 'install.rdf' === n.textContent.trim())) { -console.error('here'); let c = 7, n, z; n = doc.querySelector('a.sidebar-button[href*=".zip"]'); while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+'),a.btn.btn-sm:nth-child('+c+')'))); @@ -307,7 +306,6 @@ console.error('here'); c = doc.querySelector('div.only-with-full-nav'); if(!c || doc.defaultView.getComputedStyle(c).getPropertyValue('display') == 'block') { - console.error('with just n, n is:', n); addButton(n); } else { z = n; @@ -320,7 +318,6 @@ console.error('here'); n = n && n.firstElementChild; if( n ) { - console.error('n and z, n:', n, 'z:', z); addButton(n,z); } } From 21baca6955fe15625d1da8e6d1062473b87c6ade Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:09:46 +0200 Subject: [PATCH 12/22] Add Build metadata to elevate released version; --- install.rdf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.rdf b/install.rdf index 9029db7..d59552a 100644 --- a/install.rdf +++ b/install.rdf @@ -4,7 +4,7 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5a4 + 1.5+0001 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone From 7290bac957955d40f7524efadcc8c7b6f223b508 Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:22:44 +0200 Subject: [PATCH 13/22] Clean up; --- bootstrap.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index ca4f052..486cbe0 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -77,7 +77,7 @@ function onClickHanlder(ev) { "Don't click me more than once, reload the page to retry."); return; } - + if (this.classList.contains('disabled')) { //needed for when checking if editable file is installable return; } @@ -113,19 +113,19 @@ function onClickHanlder(ev) { .createInstance(Ci.nsIZipWriter); let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); - + zipReader.open(nFile); zipWriter.open(oFile, 0x2c); - + let p = (this.getAttribute('path') || "*/"), m = zipReader.findEntries(p + "*"); p = p.substr(2); - + if (this.hasAttribute('filepath')) { var fileName = this.getAttribute('filepath'); var useUncommitedFilePath = this.getAttribute('filepath').replace(this.getAttribute('path'), ''); //relative to path, because thats what is getting written to xpi } - + while(m.hasMore()) { let f = m.getNext(), e = zipReader.getEntry(f); @@ -145,7 +145,7 @@ function onClickHanlder(ev) { let is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); is.data = this.ownerDocument.querySelector('#blob_contents').value; zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); - } else { + } else { zipWriter.addEntryStream(n, e.lastModifiedTime, Ci.nsIZipWriter.COMPRESSION_FASTEST, zipReader.getInputStream(f), !1); @@ -183,21 +183,21 @@ function onClickHanlder(ev) { let m = aAddon.name + ' requires restart.\n\n' + 'Would you like to restart ' + Services.appinfo.name + ' now?'; - + m = Services.prompt.confirmEx(null, addon.name,m,1027,0,0,0,null,{}); - + if(!m) { let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] .createInstance(Ci.nsISupportsPRBool); - + Services.obs.notifyObservers(cancelQuit, "quit-application-requested", null); - + if(!cancelQuit.data) { Services.obs.notifyObservers(null, "quit-application-granted", null); - + Services.startup.quit( Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart @@ -207,23 +207,23 @@ function onClickHanlder(ev) { } }); }; - + aInstall.addListener({ onInstallFailed : function(aInstall) { aInstall.removeListener(this); - + done(aInstall.error); }, onInstallEnded : function(aInstall,aAddon) { aInstall.removeListener(this); - + done(aAddon.name + ' ' + aAddon.version + ' has been installed successfully.',aAddon); } }); aInstall.install(); }); - + nFile.remove(!1); } @@ -269,7 +269,7 @@ function addButton(n,u) { n.firstChild.style.verticalAlign = 'baseline'; } } - + return n; } @@ -345,7 +345,7 @@ function onPageLoad(doc) { var f = btn.firstChild; l.textContent = ' Checking if Installable...'; f.className = f.className.replace('plus','hourglass'); - + var breadcrumbs = doc.querySelectorAll('span[itemtype*=Breadcrumb]'); var breads = ['*']; for (var i=1; i { let iStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"] @@ -385,10 +385,10 @@ function onPageLoad(doc) { let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] .createInstance(Ci.nsIZipReader); - let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); - + let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + zipReader.open(nFile); - + var entries = zipReader.findEntries(null); while(entries.hasMore()) { let entryFileName = entries.getNext(); @@ -419,8 +419,8 @@ function onPageLoad(doc) { }); }); ////////////////// - - + + } } } From ecb1346af5cfc5216a1cde19847713a1df81242f Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:23:48 +0200 Subject: [PATCH 14/22] Make plugin work on all pull request pages; e.g. https://github.com/diegocr/GitHubExtIns/pull/10/commits & https://github.com/diegocr/GitHubExtIns/pull/10/files --- bootstrap.js | 2 +- install.rdf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap.js b/bootstrap.js index 486cbe0..4fd0ded 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -276,7 +276,7 @@ function addButton(n,u) { function onPageLoad(doc) { var myElseIfVar; - if(doc.location.pathname.replace(/\/[^/]+$/,'').substr(-4) === 'pull') { + if(doc.location.pathname.split('/')[3] === 'pull') { // Based on work by Jerone: https://github.com/jerone/UserScripts let r = '' + doc.location.pathname.split('/').filter(String).slice(1,2), diff --git a/install.rdf b/install.rdf index d59552a..fa7cfbc 100644 --- a/install.rdf +++ b/install.rdf @@ -4,7 +4,7 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5+0001 + 1.5+0002 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone From 7a73d889b32a7993a345913a9428b20a87331d8c Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:25:34 +0200 Subject: [PATCH 15/22] Contirubtion -> Contribution --- bootstrap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index 4fd0ded..6a05402 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -8,7 +8,7 @@ * Diego Casorran (Original Author) * Jerone * Zulkarnain K. - * Noitidart (Authored Contirubtion: "Install from Edit Page without Committing") + * Noitidart (Authored Contribution: "Install from Edit Page without Committing") * * ***** END LICENSE BLOCK ***** */ From cc955f3fcf77399ae7b5faf959b7d4a29978f9e2 Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:28:43 +0200 Subject: [PATCH 16/22] Contributor updated; --- bootstrap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index 6a05402..7be8811 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -6,7 +6,7 @@ * * Contributor(s): * Diego Casorran (Original Author) - * Jerone + * Jerone * Zulkarnain K. * Noitidart (Authored Contribution: "Install from Edit Page without Committing") * From 7397ed6ebfa4b1cc392bc2c98237579d6282c7a2 Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 20:40:34 +0200 Subject: [PATCH 17/22] Add missing screenshot, but link to AMO; --- README.md | 2 +- screenshot.png | Bin 0 -> 9913 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 screenshot.png diff --git a/README.md b/README.md index 90a02eb..26773ab 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ GitHub Extension Installer - Mozilla Extension This Add-On allows you to install browser extensions straight from GitHub Repositories, the only requirement in the current version is that the extension files are placed in the root of the repo. If that is the case (ie, a install.rdf file is found there), a new button will be added in the right-bottom side of the page as shown in the next screenshot. -![SS](https://addons.cdn.mozilla.net/img/uploads/previews/full/113/113974.png?modified=1380155370) +![GitHub Extension Installer Screenshot](https://addons.cdn.mozilla.net/user-media/previews/full/113/113974.png) **Please note the installation is performed in the background, there won't be a confirmation dialog**, you'll just get a notification indicating whether the installation succeed or failed. diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9d3d279e467452847f03f9b584c831c954380e GIT binary patch literal 9913 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 literal 0 HcmV?d00001 From 3deb0311a3aeaee11fa3a77ddc58dbf84c3ae10c Mon Sep 17 00:00:00 2001 From: Jeroen van Warmerdam Date: Mon, 6 Apr 2015 21:07:16 +0200 Subject: [PATCH 18/22] Clean up formatting with JS Beautifier; Settings are with respect to the existing code; --- .jsbeautifyrc | 22 ++++++ bootstrap.js | 197 +++++++++++++++++++++++++------------------------- install.rdf | 2 +- 3 files changed, 122 insertions(+), 99 deletions(-) create mode 100644 .jsbeautifyrc diff --git a/.jsbeautifyrc b/.jsbeautifyrc new file mode 100644 index 0000000..b1a5718 --- /dev/null +++ b/.jsbeautifyrc @@ -0,0 +1,22 @@ +{ + "indent_size": 4, + "indent_char": " ", + "eol": "\n", + "indent_level": 0, + "indent_with_tabs": true, + "preserve_newlines": true, + "max_preserve_newlines": 10, + "jslint_happy": false, + "space_after_anon_function": false, + "brace_style": "collapse", + "keep_array_indentation": false, + "keep_function_indentation": false, + "space_before_conditional": false, + "break_chained_methods": false, + "eval_code": false, + "unescape_strings": false, + "wrap_line_length": 0, + "wrap_attributes": "auto", + "wrap_attributes_indent_size": 4, + "end_with_newline": false +} diff --git a/bootstrap.js b/bootstrap.js index 7be8811..abfc9d5 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -12,7 +12,12 @@ * * ***** END LICENSE BLOCK ***** */ -let {classes:Cc,interfaces:Ci,utils:Cu,results:Cr} = Components, addon; +let { + classes: Cc, + interfaces: Ci, + utils: Cu, + results: Cr +} = Components, addon; Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -20,9 +25,8 @@ Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -function LOG(m) (m = addon.name + ' Message @ ' - + (new Date()).toISOString() + "\n> " + m, - dump(m + "\n"), Services.console.logStringMessage(m)); +function LOG(m)(m = addon.name + ' Message @ ' + (new Date()).toISOString() + "\n> " + m, + dump(m + "\n"), Services.console.logStringMessage(m)); let i$ = { onOpenWindow: function(aWindow) { @@ -50,7 +54,10 @@ function iNotify(aAddon, aMsg, callback) { if(nme == 3) try { if(aAddon) { let info = { - installs: [{addon:aAddon,name:aAddon.name + ' ' + aAddon.version}], + installs: [{ + addon: aAddon, + name: aAddon.name + ' ' + aAddon.version + }], originatingWindow: Services.wm.getMostRecentWindow('navigator:browser').gBrowser.contentWindow, QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo]) }; @@ -60,10 +67,9 @@ function iNotify(aAddon, aMsg, callback) { } catch(e) { Cu.reportError(e); } - showAlertNotification(addon.icon,addon.name,aMsg,!1,"", - (s,t) => t == "alertshow" || callback(t)); + showAlertNotification(addon.icon, addon.name, aMsg, !1, "", (s, t) => t == "alertshow" || callback(t)); } else { - if(nme) Services.prompt.alert(null,addon.name,aMsg); + if(nme) Services.prompt.alert(null, addon.name, aMsg); callback(); } @@ -73,46 +79,45 @@ function onClickHanlder(ev) { ev.preventDefault(); if(this.hasAttribute(addon.tag)) { - Services.prompt.alert(null,addon.name, + Services.prompt.alert(null, addon.name, "Don't click me more than once, reload the page to retry."); return; } - if (this.classList.contains('disabled')) { //needed for when checking if editable file is installable + if(this.classList.contains('disabled')) { //needed for when checking if editable file is installable return; } - this.setAttribute(addon.tag,1); + this.setAttribute(addon.tag, 1); this.className += ' danger disabled'; let d = this.ownerDocument, l = this.lastChild, f = this.firstChild; l.textContent = ' Installing...'; - f.className = f.className.replace(/(?:plus|check)/,'hourglass'); - d.body.appendChild(d.createElement('style')).textContent = '@keyframes ' - +addon.tag+'{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}'; + f.className = f.className.replace(/(?:plus|check)/, 'hourglass'); + d.body.appendChild(d.createElement('style')).textContent = '@keyframes ' + addon.tag + '{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}'; f.style.animation = addon.tag + ' 3s infinite linear'; - xhr(this.href || this.getAttribute('href'),data => { + xhr(this.href || this.getAttribute('href'), data => { let iStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"] .createInstance(Ci.nsIArrayBufferInputStream); - iStream.setData(data,0,data.byteLength); + iStream.setData(data, 0, data.byteLength); let nFile = FileUtils.getFile("TmpD", [Math.random()]) - oStream = FileUtils.openSafeFileOutputStream(nFile); + oStream = FileUtils.openSafeFileOutputStream(nFile); NetUtil.asyncCopy(iStream, oStream, aStatus => { if(!Components.isSuccessCode(aStatus)) { - Services.prompt.alert(null,addon.name, - 'Error ' +aStatus+ ' writing to ' +nFile.path); + Services.prompt.alert(null, addon.name, + 'Error ' + aStatus + ' writing to ' + nFile.path); } else { let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] - .createInstance(Ci.nsIZipReader), + .createInstance(Ci.nsIZipReader), zipWriter = Cc["@mozilla.org/zipwriter;1"] - .createInstance(Ci.nsIZipWriter); + .createInstance(Ci.nsIZipWriter); - let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + let oFile = FileUtils.getFile("TmpD", [addon.tag + '.xpi']); zipReader.open(nFile); zipWriter.open(oFile, 0x2c); @@ -121,7 +126,7 @@ function onClickHanlder(ev) { m = zipReader.findEntries(p + "*"); p = p.substr(2); - if (this.hasAttribute('filepath')) { + if(this.hasAttribute('filepath')) { var fileName = this.getAttribute('filepath'); var useUncommitedFilePath = this.getAttribute('filepath').replace(this.getAttribute('path'), ''); //relative to path, because thats what is getting written to xpi } @@ -133,15 +138,15 @@ function onClickHanlder(ev) { if(!(e instanceof Ci.nsIZipEntry)) continue; - let n = (e.name||f).replace(/^[^\/]+\//,'').replace(p,''); + let n = (e.name || f).replace(/^[^\/]+\//, '').replace(p, ''); if(!n) continue; if(e.isDirectory) { - zipWriter.addEntryDirectory(n,e.lastModifiedTime,!1); + zipWriter.addEntryDirectory(n, e.lastModifiedTime, !1); } else { - if (useUncommitedFilePath && n == useUncommitedFilePath) { + if(useUncommitedFilePath && n == useUncommitedFilePath) { let is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); is.data = this.ownerDocument.querySelector('#blob_contents').value; zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); @@ -156,17 +161,17 @@ function onClickHanlder(ev) { zipReader.close(); zipWriter.close(); - AddonManager.getInstallForFile(oFile,aInstall => { - let done = (aMsg,aAddon) => { + AddonManager.getInstallForFile(oFile, aInstall => { + let done = (aMsg, aAddon) => { let c = 'check'; if(typeof aMsg === 'number') { l.textContent = 'Error ' + aMsg; - aMsg = 'Installation failed ('+aMsg+')'; + aMsg = 'Installation failed (' + aMsg + ')'; c = 'alert'; } else { - if (!this.hasAttribute('filepath')) { + if(!this.hasAttribute('filepath')) { l.textContent = 'Succeed!'; - this.className = this.className.replace('danger',''); + this.className = this.className.replace('danger', ''); } else { //it is uncommited file install so allow reclicking of button l.textContent = 'Installed with Uncommitted File - Reinstall'; @@ -176,16 +181,14 @@ function onClickHanlder(ev) { } } f.style.animation = null; - f.className = f.className.replace('hourglass',c); + f.className = f.className.replace('hourglass', c); iNotify(aAddon, aMsg, aResult => { oFile.remove(!1); if(aResult !== null && aAddon && aAddon.pendingOperations) { - let m = aAddon.name + ' requires restart.\n\n' - + 'Would you like to restart ' - + Services.appinfo.name + ' now?'; + let m = aAddon.name + ' requires restart.\n\n' + 'Would you like to restart ' + Services.appinfo.name + ' now?'; m = Services.prompt.confirmEx(null, - addon.name,m,1027,0,0,0,null,{}); + addon.name, m, 1027, 0, 0, 0, null, {}); if(!m) { let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] @@ -209,16 +212,15 @@ function onClickHanlder(ev) { }; aInstall.addListener({ - onInstallFailed : function(aInstall) { + onInstallFailed: function(aInstall) { aInstall.removeListener(this); done(aInstall.error); }, - onInstallEnded : function(aInstall,aAddon) { + onInstallEnded: function(aInstall, aAddon) { aInstall.removeListener(this); - done(aAddon.name + ' ' + aAddon.version - + ' has been installed successfully.',aAddon); + done(aAddon.name + ' ' + aAddon.version + ' has been installed successfully.', aAddon); } }); aInstall.install(); @@ -231,10 +233,10 @@ function onClickHanlder(ev) { }); } -function addButton(n,u) { - if([n.nextElementSibling,n.previousElementSibling] - .some(e=>e&&~e.className.indexOf(addon.tag))) - return; +function addButton(n, u) { + if([n.nextElementSibling, n.previousElementSibling] + .some(e => e && ~e.className.indexOf(addon.tag))) + return; let p = n.parentNode; n = n.cloneNode(!0); @@ -256,11 +258,11 @@ function addButton(n,u) { if(u) { let b = n.ownerDocument.querySelector('div.breadcrumb'); - n.setAttribute('href', u ); + n.setAttribute('href', u); n.style.cursor = 'pointer'; - n.style.setProperty('box-shadow','none','important'); + n.style.setProperty('box-shadow', 'none', 'important'); n.setAttribute('path', b && b.textContent - .replace(" ",'','g').replace(/^[^/]+/,'*')||''); + .replace(" ", '', 'g').replace(/^[^/]+/, '*') || ''); if(typeof u !== 'object') { n.className += ' button primary pseudo-class-active'; @@ -279,7 +281,7 @@ function onPageLoad(doc) { if(doc.location.pathname.split('/')[3] === 'pull') { // Based on work by Jerone: https://github.com/jerone/UserScripts - let r = '' + doc.location.pathname.split('/').filter(String).slice(1,2), + let r = '' + doc.location.pathname.split('/').filter(String).slice(1, 2), v = addon.branch.getPrefType('prs') && addon.branch.getCharPref('prs') || ''; if(~v.toLowerCase().split(',').indexOf(r.toLowerCase())) { @@ -293,14 +295,13 @@ function onPageLoad(doc) { 'archive', b.join(':') + '.zip' ].join('/'); - addButton(n,u); + addButton(n, u); } - } - else if([].some.call(doc.querySelectorAll('table.files > tbody > tr > td.content'), - (n) => 'install.rdf' === n.textContent.trim())) { - let c = 7, n, z; + } else if([].some.call(doc.querySelectorAll('table.files > tbody > tr > td.content'), (n) => 'install.rdf' === n.textContent.trim())) { + let c = 7, + n, z; n = doc.querySelector('a.sidebar-button[href*=".zip"]'); - while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+'),a.btn.btn-sm:nth-child('+c+')'))); + while(c-- && !(n = doc.querySelector('a.minibutton:nth-child(' + c + '),a.btn.btn-sm:nth-child(' + c + ')'))); if(n && n.textContent.trim() === 'Download ZIP') { c = doc.querySelector('div.only-with-full-nav'); @@ -317,16 +318,16 @@ function onPageLoad(doc) { n = doc.querySelector('div.file-navigation'); n = n && n.firstElementChild; - if( n ) { - addButton(n,z); + if(n) { + addButton(n, z); } } - } - else if (/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && (myElseIfVar = doc.querySelector('.js-blob-form')) && myElseIfVar.hasAttribute('action')) { + } else if(/github\.com\/.*?\/.*?\/edit\//.test(doc.location.href) && (myElseIfVar = doc.querySelector('.js-blob-form')) && myElseIfVar.hasAttribute('action')) { var editForm = myElseIfVar; var filePath = editForm.getAttribute('action'); - let c = 7, n, z; - while(c-- && !(n=doc.querySelector('a.minibutton:nth-child('+c+'),a.btn.btn-sm:nth-child('+c+')'))); + let c = 7, + n, z; + while(c-- && !(n = doc.querySelector('a.minibutton:nth-child(' + c + '),a.btn.btn-sm:nth-child(' + c + ')'))); if(n && n.textContent.trim() === 'Download ZIP') { c = doc.querySelector('div.only-with-full-nav'); @@ -338,23 +339,23 @@ function onPageLoad(doc) { n = doc.querySelector('div.breadcrumb'); n = n && n.firstElementChild; - if( n ) { - var btn = addButton(n,z); + if(n) { + var btn = addButton(n, z); btn.className += ' danger disabled' var l = btn.lastChild; var f = btn.firstChild; l.textContent = ' Checking if Installable...'; - f.className = f.className.replace('plus','hourglass'); + f.className = f.className.replace('plus', 'hourglass'); var breadcrumbs = doc.querySelectorAll('span[itemtype*=Breadcrumb]'); var breads = ['*']; - for (var i=1; i { + xhr(btn.href || btn.getAttribute('href'), data => { let iStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"] .createInstance(Ci.nsIArrayBufferInputStream); - iStream.setData(data,0,data.byteLength); + iStream.setData(data, 0, data.byteLength); let nFile = FileUtils.getFile("TmpD", [Math.random()]) - oStream = FileUtils.openSafeFileOutputStream(nFile); + oStream = FileUtils.openSafeFileOutputStream(nFile); NetUtil.asyncCopy(iStream, oStream, aStatus => { if(!Components.isSuccessCode(aStatus)) { - Services.prompt.alert(null,addon.name, - 'Error while checking if installable error was ' +aStatus+ ' writing to ' +nFile.path); + Services.prompt.alert(null, addon.name, + 'Error while checking if installable error was ' + aStatus + ' writing to ' + nFile.path); } else { let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] - .createInstance(Ci.nsIZipReader); + .createInstance(Ci.nsIZipReader); - let oFile = FileUtils.getFile("TmpD", [addon.tag+'.xpi']); + let oFile = FileUtils.getFile("TmpD", [addon.tag + '.xpi']); zipReader.open(nFile); @@ -395,7 +396,7 @@ function onPageLoad(doc) { let entryZipFile = zipReader.getEntry(entryFileName); } - for (var i=0; i { + ['page-context-loader', 'context-loader'].forEach(e => { e = doc.getElementsByClassName(e); for(let o of e) { - new doc.defaultView.MutationObserver(m => onMutation(m,doc)) - .observe(o,{attributes:!0,attributeOldValue:!0}); + new doc.defaultView.MutationObserver(m => onMutation(m, doc)) + .observe(o, { + attributes: !0, + attributeOldValue: !0 + }); } }); onPageLoad(doc); }; getBrowser(window).addEventListener('DOMContentLoaded', domload, false); - addon.wms.set(window,domload); + addon.wms.set(window, domload); } -function xhr(url,cb) { +function xhr(url, cb) { let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] .createInstance(Ci.nsIXMLHttpRequest); let handler = ev => { - evf(m => xhr.removeEventListener(m,handler,!1)); + evf(m => xhr.removeEventListener(m, handler, !1)); switch(ev.type) { case 'load': if(xhr.status == 200) { @@ -477,22 +480,19 @@ function xhr(url,cb) { break; } default: - Services.prompt.alert(null,addon.name, - 'Error Fetching Package: '+ xhr.statusText - + ' ['+ev.type+':' + xhr.status + ']'); + Services.prompt.alert(null, addon.name, + 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']'); break; } }; - let evf = f => ['load','error','abort'].forEach(f); - evf(m => xhr.addEventListener( m, handler, false)); + let evf = f => ['load', 'error', 'abort'].forEach(f); + evf(m => xhr.addEventListener(m, handler, false)); xhr.mozBackgroundRequest = true; xhr.open('GET', url, true); xhr.channel.loadFlags |= - Ci.nsIRequest.LOAD_ANONYMOUS - | Ci.nsIRequest.LOAD_BYPASS_CACHE - | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING; + Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING; xhr.responseType = "arraybuffer"; xhr.send(null); } @@ -530,22 +530,22 @@ function unloadFromWindow(window) { } function startup(data) { - AddonManager.getAddonByID(data.id,data=> { + AddonManager.getAddonByID(data.id, data => { addon = { id: data.id, name: data.name, version: data.version, icon: data.getResourceURI("icon.png").spec, - tag: data.name.toLowerCase().replace(/[^\w]/g,''), + tag: data.name.toLowerCase().replace(/[^\w]/g, ''), wms: new WeakMap() }; - addon.branch = Services.prefs.getBranch('extensions.'+addon.tag+'.'); + addon.branch = Services.prefs.getBranch('extensions.' + addon.tag + '.'); i$.wmf(loadIntoWindowStub); Services.wm.addListener(i$); if(!addon.branch.getPrefType('nme')) { - addon.branch.setIntPref('nme',2); + addon.branch.setIntPref('nme', 2); } addon.branch.setCharPref('version', addon.version); }); @@ -560,4 +560,5 @@ function shutdown(data, reason) { } function install(data, reason) {} + function uninstall(data, reason) {} diff --git a/install.rdf b/install.rdf index fa7cfbc..5d23d57 100644 --- a/install.rdf +++ b/install.rdf @@ -4,7 +4,7 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5+0002 + 1.5+0003 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone From 8ea1daecf964183a1f4833ea6f1f2ba89542e112 Mon Sep 17 00:00:00 2001 From: yajd Date: Wed, 8 Jul 2015 14:26:06 -0700 Subject: [PATCH 19/22] Update bootstrap.js GitHub changed their editor id or something, this should fix that --- bootstrap.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index abfc9d5..c1d7aa2 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -148,7 +148,11 @@ function onClickHanlder(ev) { } else { if(useUncommitedFilePath && n == useUncommitedFilePath) { let is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); - is.data = this.ownerDocument.querySelector('#blob_contents').value; + if (this.ownerDocument.querySelector('#blob_contents')) { + is.data = this.ownerDocument.querySelector('#blob_contents').value; + } else { + is.data = this.ownerDocument.querySelector('.ace_scroller').textContents; + } zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); } else { zipWriter.addEntryStream(n, e.lastModifiedTime, From 850060d66ae67b9391598c620de69f0183170c35 Mon Sep 17 00:00:00 2001 From: yajd Date: Wed, 8 Jul 2015 14:28:26 -0700 Subject: [PATCH 20/22] Update bootstrap.js typo fixed. textContents changed to textContent --- bootstrap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index c1d7aa2..7993526 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -151,7 +151,7 @@ function onClickHanlder(ev) { if (this.ownerDocument.querySelector('#blob_contents')) { is.data = this.ownerDocument.querySelector('#blob_contents').value; } else { - is.data = this.ownerDocument.querySelector('.ace_scroller').textContents; + is.data = this.ownerDocument.querySelector('.ace_scroller').textContent; } zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); } else { From 57fb8288622ca86fcb1023b804a8b9531a05192e Mon Sep 17 00:00:00 2001 From: yajd Date: Wed, 8 Jul 2015 14:35:12 -0700 Subject: [PATCH 21/22] Update bootstrap.js ok before i was getting just what was scrolled in view code. now it gets full code --- bootstrap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.js b/bootstrap.js index 7993526..a9404be 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -151,7 +151,7 @@ function onClickHanlder(ev) { if (this.ownerDocument.querySelector('#blob_contents')) { is.data = this.ownerDocument.querySelector('#blob_contents').value; } else { - is.data = this.ownerDocument.querySelector('.ace_scroller').textContent; + is.data = this.ownerDocument.querySelector('.js-blob-contents').textContent; } zipWriter.addEntryStream(n, Date.now(), Ci.nsIZipWriter.COMPRESSION_FASTEST, is, !1); } else { From 0f4dc60720287d82340fd19e20d15110e8f21599 Mon Sep 17 00:00:00 2001 From: Noitidart Date: Wed, 8 Jul 2015 20:00:28 -0700 Subject: [PATCH 22/22] Update install.rdf Updated rev number to latest rev on AMO +001 due to @yajd fix for install uncommitted file. --- install.rdf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.rdf b/install.rdf index 5d23d57..c77cf99 100644 --- a/install.rdf +++ b/install.rdf @@ -4,7 +4,7 @@ {86054B0A-BD85-42F9-8E58-8794EC6F6EA1} 2 GitHub Extension Installer - 1.5+0003 + 1.6+0001 Diego Casorran <dcasorran@gmail.com> Install Browser Extensions straight from GitHub Repositories Jerone