forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.js
More file actions
1 lines (1 loc) · 15.8 KB
/
main.js
File metadata and controls
1 lines (1 loc) · 15.8 KB
1
define(function(require,exports,module){const ExtensionUtils=brackets.getModule("utils/ExtensionUtils");require("./colorGradientProvider"),require("./ImagePreviewProvider"),require("./numberPreviewProvider"),ExtensionUtils.loadStyleSheet(module,"QuickView.less")}),define("ImagePreviewProvider",function(require,exports,module){let FileUtils=brackets.getModule("file/FileUtils"),FileSystem=brackets.getModule("filesystem/FileSystem"),PreferencesManager=brackets.getModule("preferences/PreferencesManager"),LanguageManager=brackets.getModule("language/LanguageManager"),Strings=brackets.getModule("strings"),PathUtils=brackets.getModule("thirdparty/path-utils/path-utils"),AppInit=brackets.getModule("utils/AppInit"),QuickView=brackets.getModule("features/QuickViewManager"),Metrics=brackets.getModule("utils/Metrics"),FileViewController=brackets.getModule("project/FileViewController"),enabled,prefs=null,extensionlessImagePreview,validProtocols=["data:","http:","https:","phtauri:","asset:","ftp:","file:"];function _transformToIframePath(url){if(url&&url.startsWith("https://www.youtube.com/watch?")){const utube=new URL(url),vidLink=utube.searchParams.get("v");if(vidLink)return`https://www.youtube.com/embed/${vidLink}`}return url}function getQuickView(editor,pos,token,line){return new Promise((resolve,reject)=>{let urlRegEx=/url\(([^\)]*)\)/gi,tokenString,urlMatch,sPos,ePos;if("string"===token.type)tokenString=token.string;else for(urlMatch=urlRegEx.exec(line);urlMatch&&!(pos.ch<urlMatch.index);){if(pos.ch<=urlMatch.index+urlMatch[0].length){tokenString=urlMatch[1];break}urlMatch=urlRegEx.exec(line)}if(!tokenString)return void reject();tokenString=tokenString.replace(/(^['"])|(['"]$)/g,"");let docPath=editor.document.file.fullPath,imgPath,parsed=PathUtils.parseUrl(tokenString),hasProtocol=""!==parsed.protocol&&-1!==validProtocols.indexOf(parsed.protocol.trim().toLowerCase()),ext=parsed.filenameExtension.replace(/^\./,""),language=LanguageManager.getLanguageForExtension(ext),id=language&&language.getId(),isImage="image"===id||"svg"===id,loadFromDisk=null;if(hasProtocol&&(isImage||!ext&&extensionlessImagePreview)?imgPath=tokenString:!hasProtocol&&isImage&&(imgPath="",loadFromDisk=window.path.normalize(FileUtils.getDirectoryPath(docPath)+tokenString)),!loadFromDisk&&!imgPath)return void reject();urlMatch?(sPos={line:pos.line,ch:urlMatch.index},ePos={line:pos.line,ch:urlMatch.index+urlMatch[0].length}):(sPos={line:pos.line,ch:token.start},ePos={line:pos.line,ch:token.end});let $imgPreview=$("<div id='quick-view-image-preview'><div class='image-preview'> <img src=\""+imgPath+'"></div></div>');function _tryLoadingURLInIframe(){let $iframe=$(`<iframe class='image-preview' src="${_transformToIframePath(imgPath)}">`);$imgPreview.find(".image-preview").append($iframe)}function showHandlerWithImageURL(imageURL){let img=$imgPreview.find("img");imageURL&&(img[0].src=imageURL),img.on("load",function(){$imgPreview.append("<div class='img-size'>"+this.naturalWidth+" × "+this.naturalHeight+" "+Strings.UNIT_PIXELS+"</div>")}).on("error",function(e){img.remove(),_tryLoadingURLInIframe(),e.preventDefault()})}function _imageToDataURI(file,cb){let contentType="data:image;base64,",doNotCache=!1;file.name.endsWith(".svg")&&(contentType="data:image/svg+xml;base64,",doNotCache=!0),file.read({encoding:window.fs.BYTE_ARRAY_ENCODING,doNotCache:doNotCache},function(err,content){if(err)return void cb(err);let base64=window.btoa(new Uint8Array(content).reduce((data,byte)=>data+String.fromCharCode(byte),"")),dataURL;cb(null,contentType+base64)})}$imgPreview.attr("data-for-test",imgPath||loadFromDisk);let previewPopup={start:sPos,end:ePos,content:$imgPreview};if(loadFromDisk){let imageFile=FileSystem.getFileForPath(loadFromDisk);_imageToDataURI(imageFile,function(err,dataURL){err?reject():($imgPreview.click(function(){FileViewController.openAndSelectDocument(imageFile.fullPath,FileViewController.PROJECT_MANAGER),Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"image","click")}),showHandlerWithImageURL(dataURL),Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"image","show"),resolve(previewPopup))})}else showHandlerWithImageURL(),resolve(previewPopup)})}function setExtensionlessImagePreview(_extensionlessImagePreview,doNotSave){extensionlessImagePreview!==_extensionlessImagePreview&&(extensionlessImagePreview=_extensionlessImagePreview,doNotSave||(prefs.set("extensionlessImagePreview",enabled),prefs.save()))}(prefs=PreferencesManager.getExtensionPrefs("quickview")).definePreference("extensionlessImagePreview","boolean",!0,{description:Strings.DESCRIPTION_EXTENSION_LESS_IMAGE_PREVIEW}),setExtensionlessImagePreview(prefs.get("extensionlessImagePreview"),!0),prefs.on("change","extensionlessImagePreview",function(){setExtensionlessImagePreview(prefs.get("extensionlessImagePreview"))}),AppInit.appReady(function(){QuickView.registerQuickViewProvider(exports,["all"])}),exports.getQuickView=getQuickView,exports.QUICK_VIEW_NAME="ImagePreviewProvider"}),define("colorGradientProvider",function(require,exports,module){const ColorUtils=brackets.getModule("utils/ColorUtils"),CSSUtils=brackets.getModule("language/CSSUtils"),TokenUtils=brackets.getModule("utils/TokenUtils"),AppInit=brackets.getModule("utils/AppInit"),EditorManager=brackets.getModule("editor/EditorManager"),QuickView=brackets.getModule("features/QuickViewManager"),Strings=brackets.getModule("strings"),Metrics=brackets.getModule("utils/Metrics"),CommandManager=brackets.getModule("command/CommandManager"),MainViewManager=brackets.getModule("view/MainViewManager"),FileViewController=brackets.getModule("project/FileViewController"),Commands=brackets.getModule("command/Commands");let styleLanguages=["css","text/x-less","sass","text/x-scss","stylus"];function getQuickView(editor,pos,token,line){return new Promise((resolve,reject)=>{let gradientRegEx=/-webkit-gradient\((?:[^\(]*?(?:\((?:[^\(]*?(?:\([^\)]*?\))*?)*?\))*?)*?\)|(?:(?:-moz-|-ms-|-o-|-webkit-|:|\s)((repeating-)?linear-gradient)|(?:-moz-|-ms-|-o-|-webkit-|:|\s)((repeating-)?radial-gradient))(\((?:[^\)]*?(?:\([^\)]*?\))*?)*?\))/gi,colorRegEx=new RegExp(ColorUtils.COLOR_REGEX),mode=TokenUtils.getModeAt(editor._codeMirror,pos,!1),isStyleSheet=-1!==styleLanguages.indexOf(mode);function areParensBalanced(str){let i,nestLevel=0,len;for(isStyleSheet&&(str=CSSUtils.reduceStyleSheetForRegExParsing(str)),len=str.length,i=0;i<len;i++)switch(str[i]){case"(":nestLevel++;break;case")":nestLevel--;break;case"\\":i++}return 0===nestLevel}function execGradientMatch(line,parensBalanced){let gradientMatch=parensBalanced?gradientRegEx.exec(line):null,prefix="",colorValue;return gradientMatch&&(-1!==gradientMatch[0].indexOf("@")?gradientMatch=null:(gradientMatch[0].match(/-o-|-moz-|-ms-|-webkit-/i)&&(prefix="-webkit-"),gradientMatch[1]?colorValue=gradientMatch[1]+gradientMatch[5]:gradientMatch[3]?colorValue=gradientMatch[3]+gradientMatch[5]:gradientMatch[0]&&(colorValue=gradientMatch[0],prefix=""))),{match:gradientMatch,prefix:prefix,colorValue:colorValue}}function execColorMatch(editor,line,pos){let colorMatch,ignoreNamedColors;function hyphenOnMatchBoundary(match,line){let beforeIndex,afterIndex;if(match){if((beforeIndex=match.index-1)>=0&&"-"===line[beforeIndex])return!0;if((afterIndex=match.index+match[0].length)<line.length&&"-"===line[afterIndex])return!0}return!1}function isNamedColor(match){if(match&&match[0]&&/^[a-z]+$/i.test(match[0]))return!0}do{if(!(colorMatch=colorRegEx.exec(line)))break;if(void 0===ignoreNamedColors){let mode=TokenUtils.getModeAt(editor._codeMirror,pos,!1).name;ignoreNamedColors=-1===styleLanguages.indexOf(mode)}}while(hyphenOnMatchBoundary(colorMatch,line)||ignoreNamedColors&&isNamedColor(colorMatch));return colorMatch}function splitStyleProperty(property){let token=/((?:[^"']|".*?"|'.*?')*?)([(,)]|$)/g,recurse=function(){let array=[];for(;;){let result=token.exec(property);if("("===result[2]){let str=result[1].trim()+"("+recurse().join(",")+")";str+=(result=token.exec(property))[1],array.push(str)}else array.push(result[1].trim());if(","!==result[2])return array}};return recurse()}function isGradientColorStop(args){return args.length>0&&null!==args[0].match(colorRegEx)}function hasLengthInPixels(args){return args.length>1&&args[1].indexOf("px")>0}function ensureHexFormat(str){return/^0x/.test(str)?str.replace("0x","#"):str}function normalizeGradientExpressionForQuickview(expression){if(expression.indexOf("px")>0){let paramStart=expression.indexOf("(")+1,paramEnd=expression.lastIndexOf(")"),parameters,params=splitStyleProperty(expression.substring(paramStart,paramEnd)),lowerBound=0,upperBound=$("#quick-view-color-swatch").width(),args,thisSize,i;for(i=0;i<params.length;i++)hasLengthInPixels(args=params[i].split(" "))&&(thisSize=parseFloat(args[1]),upperBound=Math.max(upperBound,thisSize),thisSize<0&&(lowerBound=Math.min(lowerBound,thisSize)));for(upperBound+=lowerBound=Math.abs(lowerBound),i=0;i<params.length;i++)isGradientColorStop(args=params[i].split(" "))&&hasLengthInPixels(args)&&(thisSize=0===upperBound?0:(parseFloat(args[1])+lowerBound)/upperBound*100,args[1]=thisSize+"%"),params[i]=args.join(" ");expression=expression.substring(0,paramStart)+params.join(", ")+expression.substring(paramEnd)}return expression}let parensBalanced=areParensBalanced(line),gradientMatch=execGradientMatch(line,parensBalanced),match=gradientMatch.match||execColorMatch(editor,line,pos),previewCSS,startPos,endPos,found=!1;for(;match;){if(pos.ch<match.index){if(!gradientMatch.match)break;gradientMatch={match:null,prefix:"",colorValue:null}}else if(pos.ch<=match.index+match[0].length){previewCSS=gradientMatch.prefix+(gradientMatch.colorValue||match[0]),startPos={line:pos.line,ch:match.index},endPos={line:pos.line,ch:match.index+match[0].length},found=!0;break}gradientMatch.match&&(gradientMatch=execGradientMatch(line,parensBalanced)),match=gradientMatch.match||execColorMatch(editor,line,pos)}if(found){let tooltip=gradientMatch.match?"":Strings.TOOLTIP_CLICK_TO_EDIT_COLOR;previewCSS=normalizeGradientExpressionForQuickview(ensureHexFormat(previewCSS));let preview=$(`<div title="${tooltip}">\n <div id='quick-view-color-swatch' data-for-test='${previewCSS}' class='color-swatch'\n style='background: ${previewCSS}'>\n </div>\n <span style="${gradientMatch.match?"display: none;":""}">\n <i class="fa fa-edit" style="color: ${previewCSS}; margin-top:5px;"></i>\n <span style="color: ${previewCSS}; margin-top:5px;">${Strings.EDIT}</span>\n </span>\n </div>`);return preview.click(function(){if(gradientMatch.match)return;let fullEditor=EditorManager.getCurrentFullEditor();if(fullEditor&&fullEditor.document.file.fullPath!==editor.document.file.fullPath){const foundResult=MainViewManager.findInAllWorkingSets(editor.document.file.fullPath);let paneToOpen;fullEditor.length&&(paneToOpen=foundResult[0].pane),FileViewController.openAndSelectDocument(editor.document.file.fullPath,FileViewController.WORKING_SET_VIEW,paneToOpen).done(function(){(fullEditor=EditorManager.getCurrentFullEditor()).setCursorPos(startPos.line,startPos.ch,!0),CommandManager.execute(Commands.TOGGLE_QUICK_EDIT)})}else editor.setCursorPos(startPos.line,startPos.ch),CommandManager.execute(Commands.TOGGLE_QUICK_EDIT);Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"color","click")}),Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"color","show"),void resolve({start:startPos,end:endPos,content:preview})}reject()})}AppInit.appReady(function(){QuickView.registerQuickViewProvider(exports,["all"])}),exports.getQuickView=getQuickView,exports.QUICK_VIEW_NAME="colorGradientProvider"}),define("numberPreviewProvider",function(require,exports,module){let PreferencesManager=brackets.getModule("preferences/PreferencesManager"),Strings=brackets.getModule("strings"),AppInit=brackets.getModule("utils/AppInit"),QuickView=brackets.getModule("features/QuickViewManager"),Metrics=brackets.getModule("utils/Metrics"),colorGradientProvider=require("./colorGradientProvider");const PREF_ENABLED_KEY="numberEditor";let prefs=PreferencesManager.getExtensionPrefs("quickview"),enabled;prefs.definePreference("numberEditor","boolean",!0,{description:Strings.DESCRIPTION_NUMBER_QUICK_VIEW});let lastOriginId=0;function _splitNumber(numStr){try{if(numStr.length>15)return null;let split=numStr.match(/(^-?)(\d*\.?\d*)(.*)/),number=split[1]+split[2]||"",decimalPlaces=number.split(".")[1],roundTo;switch(decimalPlaces=decimalPlaces&&decimalPlaces.length||0){case 0:roundTo=1;break;case 1:roundTo=10;break;case 2:default:roundTo=100}return{number:number,units:split[3]||"",decimalPlaces:decimalPlaces,roundTo:roundTo}}catch(e){return null}}function _getWordAfterPos(editor,pos){const wordRange=editor.getWordAt(pos);wordRange.text.startsWith("%")&&(wordRange.text=wordRange.text.slice(0,1),wordRange.endPos.ch=wordRange.startPos.ch+1);const wordFull=editor.getTextBetween(wordRange.startPos,wordRange.endPos);let startChInWord=0;wordRange.startPos.line===pos.line&&wordRange.startPos.ch<pos.ch&&(startChInWord=pos.ch-wordRange.startPos.ch);const effectiveStartPos={line:wordRange.startPos.line,ch:wordRange.startPos.ch+startChInWord},effectiveEndPos=wordRange.endPos,trimmedWord=wordFull.substring(startChInWord);return{text:trimmedWord,startPos:effectiveStartPos,endPos:effectiveEndPos}}function _isCSSUnit(str){const regexPattern=/^(px|cm|mm|Q|in|pc|pt|em|ex|ch|rem|vw|vh|vmin|vmax|lh|%)$/;return regexPattern.test(str)}function getQuickView(editor,pos,token,line){return new Promise((resolve,reject)=>{let startCh=token.start,endCh=token.end,numberStr=token.string;if("string"===token.type&&enabled){const number=editor.getNumberAt(pos);if(!number)return void reject();{numberStr=number.text,startCh=number.startPos.ch,endCh=number.endPos.ch;const nextPos={line:number.endPos.line,ch:number.endPos.ch},nextWord=_getWordAfterPos(editor,nextPos);_isCSSUnit(nextWord.text.trim())&&(numberStr=editor.getTextBetween(number.startPos,nextWord.endPos),endCh=nextWord.endPos.ch)}}else if("number"!==token.type||!enabled)return void reject();let sPos={line:pos.line,ch:startCh},ePos={line:pos.line,ch:endCh},editOrigin="+NumberQuickView_"+lastOriginId++,$content=$(`<div><input type="text" value="${numberStr}" class="dial"><div>`),split=_splitNumber(numberStr);if(!split)return void reject();let changedMetricSent=!1;$content.find(".dial").knob({stopper:!1,step:1/split.roundTo,max:100/split.roundTo,width:100,height:100,fgColor:"#2893ef",fontSize:"1em",format:function(value){return Math.round(value*split.roundTo)/split.roundTo+split.units},getValue:function(userInput){let changedSplit=_splitNumber(userInput);return split.units=changedSplit&&changedSplit.units,changedSplit&&changedSplit.number},change:function(value){editor.document.batchOperation(function(){editor.setSelection(sPos,ePos);let replaceStr=Math.round(value*split.roundTo)/split.roundTo+split.units;editor.replaceRange(replaceStr,sPos,ePos,editOrigin),ePos={line:sPos.line,ch:sPos.ch+replaceStr.length},editor.setSelection(sPos,ePos)}),changedMetricSent||(Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"num","changed"),changedMetricSent=!0)},changeStart:function(){QuickView.lockQuickView()},changeEnd:function(){QuickView.unlockQuickView()}}),resolve({start:sPos,end:ePos,content:$content,exclusive:!0,editsDoc:!0}),Metrics.countEvent(Metrics.EVENT_TYPE.QUICK_VIEW,"num","show")})}function filterQuickView(popovers){let hasColorQuickView=!1;for(let popover of popovers)if(popover.providerInfo.provider.QUICK_VIEW_NAME===colorGradientProvider.QUICK_VIEW_NAME){hasColorQuickView=!0;break}return hasColorQuickView&&(popovers=popovers.filter(popover=>popover.providerInfo.provider.QUICK_VIEW_NAME!==exports.QUICK_VIEW_NAME)),popovers}prefs.on("change","numberEditor",function(){enabled=prefs.get("numberEditor")}),AppInit.appReady(function(){enabled=prefs.get("numberEditor"),QuickView.registerQuickViewProvider(exports,["html","xhtml","xml","css","less","scss","sass"])}),exports.getQuickView=getQuickView,exports.filterQuickView=filterQuickView,exports.QUICK_VIEW_NAME="numberPreviewProvider"});