From 5044edb68159e3382bab219bd0ae4562f0d63c8d Mon Sep 17 00:00:00 2001 From: Nitesh Kumar <38075523+niteskum@users.noreply.github.com> Date: Mon, 27 Aug 2018 19:08:11 +0530 Subject: [PATCH] parent fa00beb5f945caa133e706f9c0eff68c9edcecf1 author Nitesh Kumar <38075523+niteskum@users.noreply.github.com> 1535377091 +0530 committer nyteksf 1536424652 -0700 jsRefactor Rename Relative Path issue fixed (#14520) * jsRefactor Rename Realtice Path issue fixed * Addressed review comments Delete .gitignore Exclude .gitignore, config.json Repair error, Refactor error handling for localStorage Add package.json to merge repos --- .gitignore | 65 ------- package.json | 2 +- src/config.json | 102 ---------- src/editor/Editor.js | 181 ++++++++++++++++-- .../JavaScriptRefactoring/RenameIdentifier.js | 19 +- 5 files changed, 182 insertions(+), 187 deletions(-) delete mode 100644 .gitignore delete mode 100644 src/config.json diff --git a/.gitignore b/.gitignore deleted file mode 100644 index aed5c256f6b..00000000000 --- a/.gitignore +++ /dev/null @@ -1,65 +0,0 @@ -Thumbs.db - -# ignore jenkins build info -/build.prop - -# package-lock.json -package-lock.json - -# ignore node_modules created by grunt, but not more deeply-nested node_modules -/node_modules -/npm-debug.log - -# ignore node_modules inside src -/src/node_modules -/src/JSUtils/node_modules -/src/JSUtils/node/node_modules - -# ignore files copied from node_modules to src/thirdparty -/src/thirdparty/CodeMirror -/src/thirdparty/less.min.js -/src/thirdparty/preact -/src/thirdparty/preact-compat -/src/thirdparty/preact-test-utils -/src/thirdparty/simulate-event -/src/thirdparty/xtend -/src/thirdparty/acorn - -# ignore compiled files -/dist -/src/.index.html -/src/styles/brackets.min.css -/src/styles/brackets.min.css.map - -# ignore everything in the dev extension directory EXCEPT the README -# (so that the directory is non-empty and can be in git) -/src/extensions/dev/* -!/src/extensions/dev/README.* -/src/extensions/default/brackets-eslint - -/src/extensions/disabled - -# ignore .disabled file for default extensions -/src/extensions/default/*/.disabled - -# generate through grunt -/src/config.json - -#OSX .DS_Store files -.DS_Store - -# unit test working directory -/test/results -/test/temp - -# Netbeans -/nbproject - -# PhpStorm -.idea - -# Files that can be automatically downloaded that we don't want to ship with our builds -/src/extensibility/node/node_modules/request/tests/ - -# Files build by scripts -/src/thirdparty/semver.browser.js diff --git a/package.json b/package.json index ddc92dd54af..c70a7404f17 100644 --- a/package.json +++ b/package.json @@ -73,4 +73,4 @@ "url": "https://github.com/adobe/brackets/blob/master/LICENSE" } ] -} \ No newline at end of file +} diff --git a/src/config.json b/src/config.json deleted file mode 100644 index ef4e55d96b2..00000000000 --- a/src/config.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "config": { - "app_title": "Brackets", - "app_name_about": "Brackets", - "about_icon": "styles/images/brackets_icon.svg", - "how_to_use_url": "https://github.com/adobe/brackets/wiki/How-to-Use-Brackets", - "support_url": "https://github.com/adobe/brackets/wiki/Troubleshooting", - "suggest_feature_url": "https://github.com/adobe/brackets/wiki/Suggest-a-Feature", - "get_involved_url": "https://github.com/adobe/brackets/blob/master/CONTRIBUTING.md", - "glob_help_url": "https://github.com/adobe/brackets/wiki/Using-File-Filters", - "release_notes_url": "https://github.com/adobe/brackets/wiki/Release-Notes", - "homepage_url": "http://brackets.io", - "twitter_url": "https://twitter.com/brackets", - "troubleshoot_url": "https://github.com/adobe/brackets/wiki/Troubleshooting#wiki-livedev", - "twitter_name": "@brackets", - "contributors_url": "https://api.github.com/repos/adobe/brackets/contributors?per_page={0}&page={1}", - "extension_listing_url": "", - "extension_registry": "https://s3.amazonaws.com/extend.brackets/registry.json", - "extension_url": "https://s3.amazonaws.com/extend.brackets/{0}/{0}-{1}.zip", - "linting.enabled_by_default": true, - "build_timestamp": "", - "healthDataServerURL": "https://healthdev.brackets.io/healthDataLog", - "analyticsDataServerURL": "https://cc-api-data-stage.adobe.io/ingest", - "serviceKey": "brackets-service", - "environment": "stage", - "update_info_url": "https://s3.amazonaws.com/files.brackets.io/updates/prerelease/.json" - }, - "name": "Brackets", - "version": "1.14.0-0", - "apiVersion": "1.14.0", - "homepage": "http://brackets.io", - "issues": { - "url": "http://github.com/adobe/brackets/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/adobe/brackets.git", - "branch": "", - "SHA": "" - }, - "defaultExtensions": { - "brackets-eslint": "3.2.0" - }, - "dependencies": { - "anymatch": "1.3.0", - "async": "2.1.4", - "chokidar": "1.6.1", - "decompress-zip": "0.3.0", - "fs-extra": "2.0.0", - "lodash": "4.17.4", - "npm": "3.10.10", - "opn": "4.0.2", - "request": "2.79.0", - "semver": "5.3.0", - "temp": "0.8.3", - "ws": "~0.4.31" - }, - "devDependencies": { - "glob": "7.1.1", - "grunt": "0.4.5", - "husky": "0.13.2", - "jasmine-node": "1.11.0", - "grunt-jasmine-node": "0.1.0", - "grunt-cli": "0.1.9", - "phantomjs": "1.9.18", - "grunt-lib-phantomjs": "0.3.0", - "grunt-eslint": "19.0.0", - "grunt-contrib-watch": "1.0.0", - "grunt-contrib-jasmine": "0.4.2", - "grunt-template-jasmine-requirejs": "0.1.0", - "grunt-contrib-cssmin": "0.6.0", - "grunt-contrib-clean": "0.4.1", - "grunt-contrib-copy": "0.4.1", - "grunt-contrib-htmlmin": "0.1.3", - "grunt-contrib-less": "1.4.0", - "grunt-contrib-requirejs": "0.4.1", - "grunt-contrib-uglify": "0.2.0", - "grunt-contrib-concat": "0.3.0", - "grunt-targethtml": "0.2.6", - "grunt-usemin": "0.1.11", - "grunt-cleanempty": "1.0.3", - "load-grunt-tasks": "3.5.0", - "q": "1.4.1", - "rewire": "1.1.2", - "tar": "2.2.1", - "webpack": "2.2.1", - "xmldoc": "0.1.2", - "zlib": "1.0.5" - }, - "scripts": { - "prepush": "npm run eslint", - "postinstall": "grunt install", - "test": "grunt test cla-check-pull", - "eslint": "grunt eslint" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/adobe/brackets/blob/master/LICENSE" - } - ] -} \ No newline at end of file diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 3a009056ad4..75df1e5ddf9 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -78,7 +78,10 @@ define(function (require, exports, module) { HTMLUtils = require("language/HTMLUtils"), ViewUtils = require("utils/ViewUtils"), MainViewManager = require("view/MainViewManager"), - _ = require("thirdparty/lodash"); + DocumentManager = require("document/DocumentManager"), + _ = require("thirdparty/lodash"), + CompressionTools = require("thirdparty/rawdeflate"), + He = require("thirdparty/he"); /** Editor preferences */ @@ -416,7 +419,7 @@ define(function (require, exports, module) { // Create the CodeMirror instance // (note: CodeMirror doesn't actually require using 'new', but jslint complains without it) - this._codeMirror = new CodeMirror(container, { + this._codeMirror = new CodeMirror(container, { autoCloseBrackets : currentOptions[CLOSE_BRACKETS], autoCloseTags : currentOptions[CLOSE_TAGS], coverGutterNextToScrollbar : true, @@ -440,7 +443,7 @@ define(function (require, exports, module) { tabSize : currentOptions[TAB_SIZE], readOnly : isReadOnly }); - + // Can't get CodeMirror's focused state without searching for // CodeMirror-focused. Instead, track focus via onFocus and onBlur // options and track state with this._focused @@ -501,11 +504,14 @@ define(function (require, exports, module) { return $(this.getRootElement()); } }); + + // Export current CodeMirror instance to allow history persistence on file open + exports.codeMirrorRef = this._codeMirror; } - + EventDispatcher.makeEventDispatcher(Editor.prototype); EventDispatcher.markDeprecated(Editor.prototype, "keyEvent", "'keydown/press/up'"); - + Editor.prototype.markPaneId = function (paneId) { this._paneId = paneId; @@ -720,7 +726,7 @@ define(function (require, exports, module) { selectionType = "indentAtSelection"; } }); - + switch (selectionType) { case "indentAtBeginning": // Case 1 @@ -731,7 +737,7 @@ define(function (require, exports, module) { // Case 2 this._addIndentAtEachSelection(selections); break; - + case "indentAuto": // Case 3 this._autoIndentEachSelection(selections); @@ -894,7 +900,6 @@ define(function (require, exports, module) { } else { cm.replaceRange(newText, change.from, change.to, change.origin); } - } }); @@ -902,6 +907,18 @@ define(function (require, exports, module) { this._updateHiddenLines(); }; + /** + * Preference to persist undo/redo history between Brackets sessions + */ + PreferencesManager.definePreference(PERSIST_UNSAVED_CHANGES, "boolean", true, { + description: Strings.DESCRIPTION_PERSIST_UNSAVED_CHANGES + }); + + var persistUnsavedChanges = PreferencesManager.get(PERSIST_UNSAVED_CHANGES), + PERSIST_UNSAVED_CHANGES = "persistUnsavedChanges", + fullPathToFile, + currentTextObj; + /** * Responds to changes in the CodeMirror editor's text, syncing the changes to the Document. * There are several cases where we want to ignore a CodeMirror change: @@ -918,7 +935,7 @@ define(function (require, exports, module) { // Secondary editor: force creation of "master" editor backing the model, if doesn't exist yet this.document._ensureMasterEditor(); - + if (this.document._masterEditor !== this) { // Secondary editor: // we're not the ground truth; if we got here, this was a real editor change (not a @@ -927,13 +944,85 @@ define(function (require, exports, module) { // FUTURE: Technically we should add a replaceRange() method to Document and go through // that instead of talking to its master editor directly. It's not clear yet exactly // what the right Document API would be, though. - this._duringSync = true; - this.document._masterEditor._applyChanges(changeList); - this._duringSync = false; + if (!persistUnsavedChanges) { + this._duringSync = true; + this.document._masterEditor._applyChanges(changeList); + this._duringSync = false; + + // Update which lines are hidden inside our editor, since we're not going to go through + // _applyChanges() in our own editor. + this._updateHiddenLines(); + } else { + /** + * Persistent Undo History: + * If pref set, will update Undo/Redo History in localStorage with each CodeMirror sync + */ + fullPathToFile = this.document.file.fullPath, + currentTextObj = JSON.stringify(this._codeMirror.getHistory()); + var currentTxt = this._codeMirror.getValue(), + scrollPos = this.getScrollPos(), + cursorPos = this.getCursorPos(), + docTxtSpecialCharsEncoded = He.encode(currentTxt), + curTxtDeflated = RawDeflate.deflate(docTxtSpecialCharsEncoded), + codeMirrorRefs = [[cursorPos.line, cursorPos.ch, cursorPos.sticky], [scrollPos.x, scrollPos.y], [currentTextObj], [curTxtDeflated], fullPathToFile], + codeMirrorRefsToJSON = JSON.stringify(codeMirrorRefs), + unsavedDocs = []; + + // Ensure if localStorage full, empty before proceeding to write + try { + window.localStorage.setItem("loadRefs__" + fullPathToFile, codeMirrorRefsToJSON); + } catch (err) { + /** + * Persistent Undo History: + * If pref set, will update Undo/Redo History in localStorage with each CodeMirror sync + */ + fullPathToFile = this.document.file.fullPath, + currentTextObj = this._codeMirror.getHistory(); + var currentTxt = this._codeMirror.getValue(), + scrollPos = this.getScrollPos(), + cursorPos = this.getCursorPos(), + docTxtSpecialCharsEncoded = He.encode(currentTxt), + curTxtDeflated = RawDeflate.deflate(docTxtSpecialCharsEncoded), + codeMirrorRefs = [[cursorPos.line, cursorPos.ch, cursorPos.sticky], [scrollPos],[currentTextObj], [curTxtDeflated], fullPathToFile], + codeMirrorRefsToJSON = JSON.stringify(codeMirrorRefs); + + // MOVE THIS INTO ITS OWN FUNCTION (D.R.Y.): + // BUILD CODE TO SAVE ALL CODEMIRRORREFS TO LOCALSTORAGE WHEN MEM FULL: + var listOfFiles = (MainViewManager.getAllOpenFiles()); + + unsavedDocs = listOfFiles.map(function (file) { + var doc = DocumentManager.getOpenDocumentForPath(file.fullPath); + if (doc && doc.isDirty) { + doc; + } + }); - // Update which lines are hidden inside our editor, since we're not going to go through - // _applyChanges() in our own editor. - this._updateHiddenLines(); + var fileRefsToJSON = unsavedDocs.map(function (file) { + var thisCurrentFile = file, + thisFileFullPath = thisCurrentFile.file._path, + thisCurrentTxtObj = file._masterEditor._codeMirror.getValue(), + thisCurrentHistory = JSON.stringify(file._masterEditor._codeMirror.getHistory()), + thisCursorPos = file._masterEditor.getCursorPos(), + thisScrollPos = file._masterEditor.getScrollPos(), + docTxtSpecialCharsEncoded = He.encode(thisCurrentTxtObj), + deflatedCurTxt = RawDeflate.deflate(docTxtSpecialCharsEncoded); + + var refs = [[thisCursorPos.line, thisCursorPos.ch, thisCursorPos.sticky], [thisScrollPos], [thisCurrentHistory], [deflatedCurTxt], [thisFileFullPath]], refsToJSON = JSON.stringify(refs); + + return refsToJSON; + }); + + window.localStorage.clear(); // Making more room.... + + fileRefsToJSON.forEach(function (fileRefs) { // Then restore unsaved changes to localStorage + var parsedJSONRefs = JSON.parse(fileRefs), + filePathFull = parsedJSONRefs.pop().toString(), + fileRefs = JSON.stringify(parsedJSONRefs); + + window.localStorage.setItem("loadRefs__" + filePathFull, fileRefs); // Adding back one file per interation + }); + } + } } // Else, Master editor: // we're the ground truth; nothing else to do, since Document listens directly to us @@ -946,6 +1035,64 @@ define(function (require, exports, module) { // Editor dispatches a change event before this event is dispatched, because // CodeHintManager needs to hook in here when other things are already done. this.trigger("editorChange", this, changeList); + + /** + * Persistent Undo History: + * If pref set, will update Undo/Redo History in localStorage with each CodeMirror sync + */ + if (persistUnsavedChanges) { + fullPathToFile = this.document.file.fullPath, + currentTextObj = JSON.stringify(this._codeMirror.getHistory()); + var currentTxt = this._codeMirror.getValue(), + scrollPos = this.getScrollPos(), + cursorPos = this.getCursorPos(), + docTxtSpecialCharsEncoded = He.encode(currentTxt), + curTxtDeflated = RawDeflate.deflate(docTxtSpecialCharsEncoded), + codeMirrorRefs = [[cursorPos.line, cursorPos.ch, cursorPos.sticky], [scrollPos], [currentTextObj], [curTxtDeflated], fullPathToFile], + codeMirrorRefsToJSON = JSON.stringify(codeMirrorRefs), + unsavedDocs = []; + + // Ensure if localStorage full, empty before proceeding to write + try { + window.localStorage.setItem("loadRefs__" + fullPathToFile, codeMirrorRefsToJSON); + } catch (err) { + // MOVE THIS INTO ITS OWN FUNCTION (D.R.Y.): + var listOfFiles = (MainViewManager.getAllOpenFiles()); + + unsavedDocs = listOfFiles.map(function (file) { + var doc = DocumentManager.getOpenDocumentForPath(file.fullPath); + if (doc && doc.isDirty) { + return doc; + } + }); + + var fileRefsToJSON = unsavedDocs.map(function (file) { + var thisCurrentFile = file, + thisFileFullPath = thisCurrentFile.file._path, + thisCurrentTxtObj = file._masterEditor._codeMirror.getValue(), + thisCurrentHistory = JSON.stringify(file._masterEditor._codeMirror.getHistory()), + thisCursorPos = file._masterEditor.getCursorPos(), + thisScrollPos = file._masterEditor.getScrollPos(), + docTxtSpecialCharsEncoded = He.encode(thisCurrentTxtObj), + deflatedCurTxt = RawDeflate.deflate(docTxtSpecialCharsEncoded); + + var refs = [[thisCursorPos.line, thisCursorPos.ch, thisCursorPos.sticky], [thisScrollPos], [thisCurrentHistory], [deflatedCurTxt], [thisFileFullPath]], + refsToJSON = JSON.stringify(refs); + + return refsToJSON; + }); + + window.localStorage.clear(); + + fileRefsToJSON.forEach(function (fileRefs) { + var parsedJSONRefs = JSON.parse(fileRefs), + filePathFull = parsedJSONRefs.pop().toString(), + fileRefs = JSON.stringify(parsedJSONRefs); + + window.localStorage.setItem("loadRefs__" + filePathFull, fileRefs); + }); + } + } }; /** @@ -1078,7 +1225,7 @@ define(function (require, exports, module) { * Semi-private: only Document should call this. * @param {!string} text */ - Editor.prototype._resetText = function (text) { + Editor.prototype._resetText = function (text) { // nyteksf var currentText = this._codeMirror.getValue(); // compare with ignoring line-endings, issue #11826 @@ -2777,7 +2924,7 @@ define(function (require, exports, module) { }); }); }); - + // Define public API exports.Editor = Editor; exports.BOUNDARY_CHECK_NORMAL = BOUNDARY_CHECK_NORMAL; diff --git a/src/extensions/default/JavaScriptRefactoring/RenameIdentifier.js b/src/extensions/default/JavaScriptRefactoring/RenameIdentifier.js index 13448e9e6bb..6fa53b5f48e 100644 --- a/src/extensions/default/JavaScriptRefactoring/RenameIdentifier.js +++ b/src/extensions/default/JavaScriptRefactoring/RenameIdentifier.js @@ -29,7 +29,8 @@ define(function (require, exports, module) { Session = brackets.getModule("JSUtils/Session"), MessageIds = brackets.getModule("JSUtils/MessageIds"), TokenUtils = brackets.getModule("utils/TokenUtils"), - Strings = brackets.getModule("strings"); + Strings = brackets.getModule("strings"), + ProjectManager = brackets.getModule("project/ProjectManager"); var session = null, // object that encapsulates the current session state keywords = ["define", "alert", "exports", "require", "module", "arguments"]; @@ -97,8 +98,22 @@ define(function (require, exports, module) { var result = new $.Deferred(); function isInSameFile(obj, refsResp) { + var projectRoot = ProjectManager.getProjectRoot(), + projectDir, + fileName = ""; + if (projectRoot) { + projectDir = projectRoot.fullPath; + } + + // get the relative path of File as Tern can also return + // references with file name as a relative path wrt projectRoot + // so refernce file name will be compared with both relative and absolute path to check if it is same file + if (projectDir && refsResp && refsResp.file && refsResp.file.indexOf(projectDir) === 0) { + fileName = refsResp.file.slice(projectDir.length); + } // In case of unsaved files, After renameing once Tern is returning filename without forward slash - return (obj && (obj.file === refsResp.file || obj.file === refsResp.file.slice(1, refsResp.file.length))); + return (obj && (obj.file === refsResp.file || obj.file === fileName + || obj.file === refsResp.file.slice(1, refsResp.file.length))); } /**