Best JavaScript code snippet using cypress
nsFILEfox.js
Source:nsFILEfox.js
1/**2 * Copyright (c) 2010 Marat Nepomnyashy maratbn@gmail3 * All rights reserved.4 *5 * Module: FILEfox/components/nsFILEfox.js6 *7 * Redistribution and use in source and binary forms, with or without8 * modification, are permitted provided that the following conditions are met:9 * * Redistributions of source code must retain the above copyright10 * notice, this list of conditions and the following disclaimer.11 * * Redistributions in binary form must reproduce the above copyright12 * notice, this list of conditions and the following disclaimer in the13 * documentation and/or other materials provided with the distribution.14 * * Neither the name of the <organization> nor the15 * names of its contributors may be used to endorse or promote products16 * derived from this software without specific prior written permission.17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.28 * 29 *30 * The XPCOM component 'nsFILEfox' is declared here.31 */32Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");33nsFILEfoxTextFileReadOut_interfaces = [34 Components.interfaces.nsIFILEfoxTextFileReadOut,35 Components.interfaces.nsIFILEfoxTextFileRead,36 Components.interfaces.nsIFILEfoxTextFile,37 Components.interfaces.nsIClassInfo,38 Components.interfaces.nsISupports39 ];40function nsFILEfoxTextFileReadOut() {41}42nsFILEfoxTextFileReadOut.prototype = {43 // Interaface nsIClassInfo:44 classDescription: "This XPCOM component is part of the FILEfox Firefox extension.",45 classID: Components.ID("{9d163612-2c51-430d-9460-62cb0f2ffe46}"),46 contractID: "@marat.nepomnyashy/ns_file_fox_text_file_read_out;1",47 flags: Components.interfaces.nsIClassInfo.DOM_OBJECT,48 implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,49 getHelperForLanguage: function(language) {50 return null;51 },52 getInterfaces: function(totalInterfaces) {53 totalInterfaces.value = nsFILEfoxTextFileReadOut_interfaces.length;54 return nsFILEfoxTextFileReadOut_interfaces;55 },56 // Interface nsISupports:57 QueryInterface: XPCOMUtils.generateQI(nsFILEfoxTextFileReadOut_interfaces),58 // Interface nsIFILEfoxTextFile:59 /**60 * The encoding with which this text file is encoded.61 */62 encoding: "",63 /**64 * Total number of characters in the text file.65 */66 totalChars: 0,67 /**68 * Total number of lines in the text file.69 *70 * Have to store the text file line by line rather than in a single string, as otherwise a huge file requiring to71 * be accomodated in a huge string would overwhelm the browser's JavaScript engine.72 */73 totalLines: 0,74 /**75 * Returns a single line out of the text file, including the line termination carriage return character sequence.76 *77 * @param indexLine Number 0-based index of the line.78 */79 getLine: function(indexLine) {80 return this._arrLines && this._arrLines[indexLine];81 },82 /**83 * Returns a single line out of the text file, stripped of the whitespace bounding it.84 *85 * @param indexLine Number 0-based index of the line.86 */87 getLineStripped: function(indexLine) {88 var strLine = this.getLine(indexLine);89 arrBreakdownForLine = strLine && strLine.match(/^\s*(.+\S+)\s*$/);90 return arrBreakdownForLine && arrBreakdownForLine.length == 2 && arrBreakdownForLine[1] || null;91 },92 /**93 * Returns a single non-whitespace token with the index specified on the line with the index specified.94 *95 * @param indexToken Number 0-based index of the token on the line.96 * @param indexLine Number 0-based index of the line.97 *98 * Note that the token index is specified before the line index.99 */100 getTokenOnLine: function(indexToken, indexLine) {101 this._insureTokenLineExists(indexLine);102 return this._arrLineTokens[indexLine][indexToken];103 },104 /**105 * Returns the total number of non-whitespace tokens on the line with the index specified.106 *107 * @param indexLine Number 0-based index of the line.108 */109 getTotalTokensOnLine: function(indexLine) {110 this._insureTokenLineExists(indexLine);111 return this._arrLineTokens[indexLine].length;112 },113 setData: function(strEncoding, totalChars, totalLines, arrLines) {114 this.encoding = strEncoding;115 this.totalChars = totalChars;116 this.totalLines = totalLines;117 this._arrLines = arrLines;118 this._arrLineTokens = [];119 },120 _insureTokenLineExists: function(indexLine) {121 if (this._arrLineTokens[indexLine]) return;122 var strLineStripped = this.getLineStripped(indexLine);123 this._arrLineTokens[indexLine] = strLineStripped && strLineStripped.split(/\s/) || [];124 }125}126nsFILEfox_interfaces = [127 Components.interfaces.nsIFILEfox,128 Components.interfaces.nsIClassInfo,129 Components.interfaces.nsISupports130 ];131function nsFILEfox() {132}133nsFILEfox.prototype = {134 // Interaface nsIClassInfo:135 classDescription: "This XPCOM component is part of the FILEfox Firefox extension.",136 classID: Components.ID("{7faaf2e7-a039-4a86-89f7-1406110c908c}"),137 contractID: "@marat.nepomnyashy/ns_file_fox;1",138 flags: Components.interfaces.nsIClassInfo.DOM_OBJECT,139 implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,140 getHelperForLanguage: function(language) {141 return null;142 },143 getInterfaces: function(totalInterfaces) {144 totalInterfaces.value = nsFILEfox_interfaces.length;145 return nsFILEfox_interfaces;146 },147 _xpcom_categories: [{148 category: "JavaScript global property",149 entry: 'nsFILEfox'150 }],151 // Interface nsISupports:152 QueryInterface: XPCOMUtils.generateQI(nsFILEfox_interfaces),153 154 // Interface nsIFILEfox:155 /**156 * Returns the version of the currently installed FILEfox extension.157 */158 getVersion: function() {159 var application = this._obtainComponentService(160 null,161 '@mozilla.org/fuel/application;1',162 Components.interfaces.fuelIApplication);163 var extension = application && application.extensions && application.extensions.get('FILEfox@maratbn.com');164 return extension && extension.version;165 },166 /**167 * Returns 'true' if the version of the currently installed FILEfox extension is at least the version specified.168 *169 * @param strVersionTest String String identifying the version to test for in x.y.z format.170 */171 isVersionAtLeast: function(strVersionTest) {172 if (!strVersionTest) return false;173 var strVersionCurrent = this.getVersion();174 var arrVersionTest = strVersionTest.split('.');175 var arrVersionCurrent = strVersionCurrent.split('.');176 var lengthMin = Math.min(arrVersionTest.length, arrVersionCurrent.length);177 for (var i = 0; i < lengthMin; i++) {178 var fragVersionTest = parseInt(arrVersionTest[i]);179 if (isNaN(fragVersionTest)) return false;180 var fragVersionCurrent = parseInt(arrVersionCurrent[i]);181 if (fragVersionTest < fragVersionCurrent) return true;182 if (fragVersionCurrent < fragVersionTest) return false;183 }184 return (arrVersionTest.length <= arrVersionCurrent.length);185 },186 /**187 * Causes the FILEfox extension to request from the user to manually select an ASCII text file to load. Upon188 * user approval FILEfox will initiate a Mozilla-internal synchroneous file loading routine via XPCOM, and then189 * return the file contents in a data object corresponding to the 'nsIFILEfoxTextFileRead' interface, or a falsy190 * value on failure.191 *192 * The returned data object should be assigned to a private local variable inside the calling function and later193 * accessed via closure to prevent exposing it to other scripts on the page.194 *195 * @param strUPFile String A string identifying the requesting application's upload policy196 * for file contents. Only valid upload policies are accepted.197 * Valid upload policies for file contents are:198 *199 * 'upload_policy_file_never' File contents are never uploaded.200 * 'upload_policy_file_always' File contents are always uploaded.201 * 'upload_policy_file_asks_later' Application will later ask the202 * user for permission to upload.203 *204 * @param strUPDerivedData String A string identifying the requesting application's upload policy205 * for data derived from file contents. Only valid upload policies206 * are accepted. Valid upload policies for derived data are:207 *208 * 'upload_policy_derived_data_never' Derived data is never uploaded.209 * 'upload_policy_derived_data_always' Derived data is always uploaded.210 * 'upload_policy_derived_data_asks_later' Application will later ask the211 * user for permission to upload.212 *213 * @param strApplicationName String A short textual name identifying the JavaScript214 * application requesting the file. The application will be215 * identified to the user by this name.216 *217 * @param strMessageToUser String A longer textual request message providing file loading218 * instructions to the user, and explaining why the219 * JavaScript application is requesting the file.220 */221 requestLoadASCIIFile: function(strUPFile, strUPDerivedData, strApplicationName, strMessageToUser) {222 // Get a reference to the DOM window to be able to communicate with the user:223 var window_mediator = this._obtainComponentService(224 null,225 '@mozilla.org/appshell/window-mediator;1',226 Components.interfaces.nsIWindowMediator);227 var window = window_mediator && window_mediator.getMostRecentWindow('navigator:browser');228 if (!window) return null;229 if (!this._doConfirmationMsg( window,230 window_mediator,231 strUPFile,232 strUPDerivedData,233 strApplicationName,234 strMessageToUser)) return null;235 // Obtain the user's Desktop directory:236 var directory_service = this._obtainComponentService(237 window,238 '@mozilla.org/file/directory_service;1',239 Components.interfaces.nsIProperties);240 if (!directory_service) return null;241 var fileDesktop = directory_service.get('Desk', Components.interfaces.nsIFile);242 if (!fileDesktop || !fileDesktop.path) {243 window.alert("nsFILEfox error: Unable to determine the user's desktop directory.");244 return null;245 }246 // Display the file picker:247 const nsi_file_picker = Components.interfaces.nsIFilePicker;248 var file_picker = this._obtainComponentInstance(249 window,250 '@mozilla.org/filepicker;1',251 nsi_file_picker);252 if (!file_picker) return null;253 file_picker.init(window, "Loading an ASCII text file for website via the FILEfox Firefox extension.", nsi_file_picker.modeOpen);254 file_picker.appendFilters(nsi_file_picker.filterAll);255 var ret = file_picker.show();256 if (ret !== nsi_file_picker.returnOK) return null;257 var file = file_picker.file;258 if (!file || !file.path) {259 window.alert("nsFILEfox error: Unable to determine which file the user has decided to open.");260 return null;261 }262 var file_input_stream = this._obtainComponentInstance(263 window,264 '@mozilla.org/network/file-input-stream;1',265 Components.interfaces.nsIFileInputStream);266 if (!file_input_stream) return null;267 file_input_stream.init(file, 1, 0, false);268 var converter_input_stream = this._obtainComponentInstance(269 window,270 '@mozilla.org/intl/converter-input-stream;1',271 Components.interfaces.nsIConverterInputStream);272 if (!converter_input_stream) return null;273 var strEncoding = 'us-ascii';274 converter_input_stream.init(275 file_input_stream,276 strEncoding,277 file_input_stream.available(),278 converter_input_stream.DEFAULT_REPLACEMENT_CHARACTER);279 var arrContents = [];280 for (var isThereMore = true; isThereMore;) {281 var objRead = {};282 var totalToRead = file_input_stream.available();283 isThereMore = converter_input_stream.readString(totalToRead, objRead);284 arrContents.push(objRead.value);285 }286 converter_input_stream.close();287 // The following splits the string with the text file contents into a line by line array.288 var strContents = arrContents.join("");289 var arrSplit = strContents.split(/(\r\n|\r|\n)/);290 // The 'arrSplit' variable is an array where the line text and the line delimiters are at separate indices.291 // Need to process that into another array where the line delimiters are appended to the ends of their associated lines.292 var arrLines = [];293 var strLine = "";294 for (var i = 0; i < arrSplit.length; i ++) {295 strLine += arrSplit[i];296 if (strLine.match(/\r\n|\r|\n/)) {297 arrLines.push(strLine);298 strLine = "";299 }300 }301 if (strLine) arrLines.push(strLine);302 var file_fox_text_file = this._obtainComponentInstance(303 window,304 '@marat.nepomnyashy/ns_file_fox_text_file_read_out;1',305 Components.interfaces.nsIFILEfoxTextFileReadOut);306 file_fox_text_file.setData(strEncoding, strContents.length, arrLines.length, arrLines);307 return file_fox_text_file;308 },309 _analyzeURL: function(strURL) {310 if (!strURL) return null;311 var arrURLBreakdown = strURL.match(/^((\w+):\/\/(([\d\w-]+\.)*([\d\w-]+))(:\d+)?)\/.*$/);312 var strServerAddress = arrURLBreakdown && arrURLBreakdown.length > 1 && arrURLBreakdown[1];313 var strProtocol = arrURLBreakdown && arrURLBreakdown.length > 2 && arrURLBreakdown[2];314 var strServer = arrURLBreakdown && arrURLBreakdown.length > 3 && arrURLBreakdown[3];315 var strPort = arrURLBreakdown && arrURLBreakdown.length > 4 && arrURLBreakdown[4];316 if (strProtocol == 'http' && !strPort) strPort = 80;317 if (strProtocol == 'https' && !strPort) strPort = 443;318 var arrURLBreakdownForFile = strURL.match(/^(file:\/\/\/(.+))$/);319 strProtocol = strProtocol || arrURLBreakdownForFile && arrURLBreakdownForFile.length > 1 && 'file';320 var strOriginAddress = arrURLBreakdownForFile && arrURLBreakdownForFile.length > 0 && arrURLBreakdownForFile[1];321 var strFilename = arrURLBreakdownForFile && arrURLBreakdownForFile.length > 1 && arrURLBreakdownForFile[2];322 if (!strOriginAddress) strOriginAddress = strServerAddress;323 return {324 protocol: strProtocol,325 server: strServer,326 port: strPort,327 origin_addr: strOriginAddress,328 server_addr: strServerAddress,329 filename: strFilename,330 url: strURL331 };332 },333 _determineIfDomainsDiffer: function(objURLData1, objURLData2) {334 if (!objURLData1 || !objURLData2) return true; // Non-existant addresses are considered different domains.335 if (objURLData1.protocol != objURLData2.protocol) return true; // Different protocols are considered different domains.336 if (objURLData1.port != objURLData2.port) return true; // Different port numbers are considered different domains.337 // For now just comparing "origin addresses".338 if (!objURLData1.strOriginAddress || !objURLData2.strOriginAddress || (objURLData1.strOriginAddress != objURLData2.strOriginAddress)) return true;339 return false;340 },341 _doConfirmationMsg: function(window, window_mediator, strUPFile, strUPDerivedData, strApplicationName, strMessageToUser) {342 var strUPFileDesc = null, strUPDerivedDataDesc = null;343 switch (strUPFile) {344 case 'upload_policy_file_never':345 strUPFileDesc = "File contents are never uploaded.";346 break;347 case 'upload_policy_file_always':348 strUPFileDesc = "File contents are always uploaded.";349 break;350 case 'upload_policy_file_asks_later':351 strUPFileDesc = "Application will later ask the user for permission to upload file contents.";352 break;353 }354 switch (strUPDerivedData) {355 case 'upload_policy_derived_data_never':356 strUPDerivedDataDesc = "Derived data is never uploaded.";357 break;358 case 'upload_policy_derived_data_always':359 strUPDerivedDataDesc = "Derived data is always uploaded.";360 break;361 case 'upload_policy_derived_data_asks_later':362 strUPDerivedDataDesc = "Application will later ask the user for permission to upload derived data.";363 break;364 }365 var arrMessageFromDOM = strMessageToUser && strMessageToUser.split(/\s/);366 var arrMessageFromDOMLines = [];367 for (var i = 0; i < arrMessageFromDOM.length;) {368 var line = "", maxlen = 75;369 for (; i < arrMessageFromDOM.length; i++) {370 if (line.length == 0 && arrMessageFromDOM[i].length >= maxlen) {371 line = arrMessageFromDOM[i];372 i++;373 break;374 } else if ((line.length + arrMessageFromDOM[i].length) >= maxlen) {375 break;376 } else {377 if (line.length > 0) line += " ";378 line += arrMessageFromDOM[i];379 }380 }381 if (line.length > 0) arrMessageFromDOMLines.push(line);382 }383 var arrMessage = [];384 arrMessage.push( "A website-embedded JavaScript application identifying itself as '", strApplicationName, "' is requesting to load an ASCII text file through the FILEfox Firefox extension.\r\n\r\n");385 if (strUPFileDesc) {386 arrMessage.push( "Application-advertised file contents upload policy for this request: ", strUPFileDesc, "\r\n");387 } else {388 arrMessage.push( "The application did not specify a valid upload policy for file contents. Valid upload policies for file contents are:\r\n",389 " * 'upload_policy_file_never'\r\n",390 " File contents are never uploaded.\r\n",391 " * 'upload_policy_file_always'\r\n",392 " File contents are always uploaded.\r\n",393 " * 'upload_policy_file_asks_later'\r\n",394 " Application will later ask the user for permission to upload.\r\n\r\n");395 }396 if (strUPDerivedDataDesc) {397 arrMessage.push( "Application-advertised derived data upload policy for this request: ", strUPDerivedDataDesc, "\r\n");398 } else {399 arrMessage.push( "The application did not specify a valid upload policy for derived data. Valid upload policies for derived data are:\r\n",400 " * 'upload_policy_derived_data_never'\r\n",401 " Derived data is never uploaded.\r\n",402 " * 'upload_policy_derived_data_always'\r\n",403 " Derived data is always uploaded.\r\n",404 " * 'upload_policy_derived_data_asks_later'\r\n",405 " Application will later ask the user for permission to upload.\r\n");406 }407 arrMessage.push( "\r\n");408 if (!strUPFileDesc || !strUPDerivedDataDesc) {409 arrMessage.push( "This file request has been aborted because the requesting JavaScript application has not specified valid upload policie(s) supported in this FILEfox extension version ", this.getVersion(), ".\r\n\r\n");410 }411 arrMessage.push( "Warning: Malicious applications may not honor advertised upload policies.\r\n\r\n");412 arrMessage.push( "The JavaScript application is operating through a series of JavaScript routines downloaded from the following server(s) / domain(s):\r\n\r\n");413 var totalScripts3rdParty = 0;414 var arrServers = this._obtainListOrigins(window_mediator);415 for (var i = 0; i < arrServers.length; i++) {416 var objServer = arrServers[i];417 arrMessage.push( " * ", objServer.origin_addr);418 if (objServer.isScript3rdParty) {419 for (var j = objServer.origin_addr.length; j < 50; j++) { // This makes the 3rd party script warnings are relatively aligned.420 arrMessage.push(" ");421 }422 arrMessage.push( " <-- 3-rd party script");423 totalScripts3rdParty++;424 }425 arrMessage.push( "\r\n");426 }427 arrMessage.push( "\r\n");428 if (totalScripts3rdParty > 0) {429 arrMessage.push( "Warning: Detected at least " + totalScripts3rdParty + " 3-rd party script(s) involved in this file loading request. ");430 arrMessage.push( "3-rd party JavaScript can be legitimate, but it is also known to be used by malicious servers for cross-site scripting (XSS) attacks. ");431 arrMessage.push( "Such a malicious XSS \"attack\" could upload your private file to the malicious 3-rd party server.\r\n\r\n");432 }433 if (!strUPFileDesc || !strUPDerivedDataDesc) {434 window.alert(arrMessage.join(""));435 return false;436 }437 arrMessage.push( "Do not continue with the file loading process if you do not trust any one of the server(s) / domain(s) listed above.\r\n\r\n");438 if (arrMessageFromDOMLines.length > 0) {439 arrMessage.push( "Message from the JavaScript application: ",440 "\r\n\r\n");441 for (var i = 0; i < arrMessageFromDOMLines.length; i++) {442 arrMessage.push(" --> ", arrMessageFromDOMLines[i], "\r\n");443 }444 arrMessage.push( "\r\n",445 "Use your discretion regardless of what the message above says. ");446 } else {447 arrMessage.push( "The application has not provided an explanation as to which file it is requesting, or why. ",448 "Therefore, continuing not recommended. ");449 }450 arrMessage.push( "\r\n\r\n",451 "Do not load files containing authentication, operating system configuration, or financial information. ",452 "Make sure to read the information at [Tools -> FILEfox -> About] before using this feature. ",453 "\r\n\r\n",454 "Are you sure you want to continue to the file selection dialog box?");455 return window.confirm(arrMessage.join(""));456 },457 _obtainComponentClass: function(window, strComponentContractID) {458 var objComponent = Components.classes[strComponentContractID];459 if (!objComponent) {460 if (window) window.alert("nsFILEfox error: Unable to obtain the XPCOM class with the contract ID of '" + strComponentContractID + "'.");461 return null;462 }463 return objComponent;464 },465 _obtainComponentInstance: function(window, strComponentContractID, objInterface) {466 try {467 var objComponent = this._obtainComponentClass(window, strComponentContractID);468 if (!objComponent) return null;469 var objInstance = objComponent.createInstance(objInterface);470 if (!objInstance) {471 if (window) window.alert("nsFILEfox error: Unable to create an instance of the XPCOM class with the contract ID of '" + strComponentContractID + "'.");472 return null;473 }474 return objInstance;475 } catch (e) {476 if (window) {477 window.alert("nsFILEfox error: Unable to create an instance of the XPCOM class with the contract ID of '" + strComponentContractID + "'. Caught exception: " + e);478 return null;479 } else {480 throw e;481 }482 }483 },484 _obtainComponentService: function(window, strComponentContractID, objInterface) {485 try {486 var objComponent = this._obtainComponentClass(window, strComponentContractID);487 if (!objComponent) return null;488 var objService = objComponent.getService(objInterface);489 if (!objService) {490 if (window) window.alert("nsFILEfox error: Unable to obtain the service of the XPCOM class with the contract ID of '" + strComponentContractID + "'.");491 return null;492 }493 return objService;494 } catch (e) {495 if (window) {496 window.alert("nsFILEfox error: Unable to obtain the service of the XPCOM class with the contract ID of '" + strComponentContractID + "'. Caught exception: " + e);497 return null;498 } else {499 throw e;500 }501 }502 },503 _obtainListOrigins: function(window_mediator) {504 var mapOrigins = {};505 var arrOrigins = [];506 var arrStackInfo = this._obtainStackInfo();507 var originLast = arrStackInfo.pop();508 var strOriginLast = originLast && originLast.origin_addr;509 var objWebpageHierarchy = this._obtainWebpageHierarchy(window_mediator);510 for (var i = 0; i < arrStackInfo.length; i++) {511 var strOriginAddress = arrStackInfo[i].origin_addr;512 if (strOriginAddress == strOriginLast) continue;513 if (!mapOrigins[strOriginAddress]) {514 var isScript3rdParty = false;515 var strURLStack = arrStackInfo[i].url;516 for (var j = 0; j < objWebpageHierarchy.scripts3rdParty.length; j++) {517 var objScript3rdParty = objWebpageHierarchy.scripts3rdParty[j];518 if (strURLStack == objScript3rdParty.url_data.url) {519 isScript3rdParty = true;520 break;521 }522 }523 arrOrigins.push(524 {525 isScript3rdParty: isScript3rdParty,526 origin_addr: strOriginAddress527 });528 mapOrigins[strOriginAddress] = true;529 }530 }531 return arrOrigins;532 },533 _obtainStackInfo: function() {534 try {535 throw new Error("This is not really an error, just a way to obtain the stack info.");536 } catch (e) {537 var arrStack = e.stack.split(/\r\n|\r|\n/);538 arrStack = arrStack.reverse();539 var arrStackInfo = [];540 for (var i = 0; i < arrStack.length; i++) {541 var strScope = arrStack[i];542 if (!strScope) continue;543 var arrURL = strScope.match(/^.+@(.+)#?:.+$/);544 var strURL = arrURL && arrURL.length > 1 && arrURL[1];545 if (strURL) arrStackInfo.push(this._analyzeURL(strURL));546 }547 return arrStackInfo;548 }549 },550 _obtainWebpageHierarchy: function(window_mediator) {551 var arrWebpages = [];552 var arrScripts3rdParty = [];553 var that = this;554 function _processFrames(windowWithFrames) {555 if (!windowWithFrames.frames) return;556 for (var i = 0; i < windowWithFrames.frames.length; i++) {557 var windowFrame = windowWithFrames[i];558 _processFrames(windowFrame);559 if (!windowFrame.document) continue;560 var strURL = windowFrame.document.documentURI;561 if (strURL == 'about:blank') continue;562 var objURLDataWP = that._analyzeURL(strURL);563 if (objURLDataWP.protocol == 'chrome') continue;564 var arrScriptSRCs = [];565 var arrScripts = windowFrame.document.getElementsByTagName('script');566 if (arrScripts) {567 for (var j = 0; j < arrScripts.length; j++) {568 var elemScript = arrScripts[j];569 var attrSRC = elemScript.attributes && elemScript.attributes.getNamedItem('src');570 var strSRC = attrSRC && attrSRC.value;571 if (strSRC) {572 var objURLDataScript = that._analyzeURL(strSRC);573 var areDomainsDifferent = that._determineIfDomainsDiffer(objURLDataWP, objURLDataScript);574 var objScript = {575 isScript3rdParty: areDomainsDifferent,576 url_data: objURLDataScript577 };578 arrScriptSRCs.push(objScript);579 if (areDomainsDifferent) arrScripts3rdParty.push(objScript);580 }581 }582 }583 arrWebpages.push(584 {585 url_data: objURLDataWP,586 scripts: arrScriptSRCs587 });588 }589 }590 var enumeration = window_mediator.getEnumerator('navigator:browser');591 while (enumeration.hasMoreElements()) {592 _processFrames(enumeration.getNext());593 }594 return {595 scripts3rdParty: arrScripts3rdParty,596 webpages: arrWebpages597 };598 }599};600var components = [nsFILEfox, nsFILEfoxTextFileReadOut];601function NSGetModule(compMgr, fileSpec) {602 return XPCOMUtils.generateModule(components);...
homeController.js
Source:homeController.js
1(function () {2 "use strict";3 angular.module("app").controller("homeController", function ($q, $rootScope, $scope, $filter, $state, $mdDialog, $mdMedia, $timeout, uiGmapGoogleMapApi, baseService, parkingSlotService) {4 //$scope.Radius = 5;5 $scope.currentLocation = undefined;6 $scope.searchingLocation = undefined;7 $scope.sortList = [{ id: 1, name: "distance", text: "Khoảng cách" }, { id: 2, name: "lowPrice", text: "Giá thấp nhất" }, { id: 3, name: "highPrice", text: "Giá cao nhất" }];8 $scope.sortBy = $scope.sortList[0];9 $scope.filterList = [10 { id: 0, name: "", text: "Bất kỳ" },11 { id: 1, name: "IsOpen247", text: "Má» cá»a 24/7" },12 { id: 2, name: "IsWeekendAvailable", text: "Äáºu xe cuá»i tuần" },13 { id: 3, name: "IsCoveredParking", text: "Có mái che" },14 { id: 4, name: "IsOvernightParking", text: "Äáºu xe qua Äêm" },15 { id: 5, name: "IsBusParking", text: "Äáºu Äược xe bus" },16 { id: 6, name: "IsCarWashingServiceAvailable", text: "Có rá»a xe" },17 ];18 $scope.filterByItems = [$scope.filterList[0]];19 $scope.showList = false;20 $scope.loading = true;21 $scope.getSelectedFilters = function() {22 return "Lá»c theo: " + $scope.filterByItems.map(function (elem) {23 return elem.text;24 }).join(", ");25 }26 //27 // Google Map options28 $scope.map = {29 center: { latitude: 16.053174, longitude: 108.202842 },30 zoom: 14,31 markers: [],32 doClusterMarkers: false,33 currentClusterType: 'standard',34 clusterTypes: baseService.ClusterTypeNames,35 selectClusterType: 'standard',36 selectedClusterTypes: baseService.ClusterTypes,37 clusterOptions: baseService.ClusterTypes.standard,38 clickedMarker: {39 id: 0,40 options: {}41 },42 events: {43 tilesloaded: function (map) {44 if (!$scope.mapInstance) {45 $scope.mapInstance = map;46 //47 // Get current location48 if (navigator.geolocation) {49 try {50 navigator.geolocation.getCurrentPosition(function (position) {51 setCurrentLocation(position.coords);52 // Search slot providers 53 $scope.searchProviders(position.coords);54 });55 } catch (e) { }56 }57 }58 }59 }60 };61 // Radius slider62 $scope.slider = {63 value: 5000,64 options: {65 showSelectionBar: true,66 floor: 1000,67 ceil: 50000,68 step: 100,69 translate: function (value) {70 var text = (value / 1000);71 if (value % 1000 === 0)72 text += '.0';73 return 'Bán kÃnh ' + text + ' km';74 },75 hideLimitLabels: true,76 keyboardSupport: false,77 onEnd: function (sliderId, modelValue, highValue, pointerType) {78 var location = $scope.searchingLocation ? $scope.searchingLocation : $scope.currentLocation;79 if (location)80 $scope.searchProviders(location);81 }82 }83 };84 //85 // Show current location and set it as center in Google Map86 var setCurrentLocation = function (coords) {87 $scope.map.center = { latitude: coords.latitude, longitude: coords.longitude };88 var image = {89 url: '/Images/pin/user_location_icon.png',90 size: new google.maps.Size(30, 37),91 origin: new google.maps.Point(0, 0),92 anchor: new google.maps.Point(15, 37)93 };94 $scope.currentLocation = {95 id: -1,96 latitude: coords.latitude,97 longitude: coords.longitude,98 title: 'Bạn Äang á» Äây',99 options: {100 icon: image,101 draggable: false,102 animation: 0,103 label: "",104 title: "Bạn Äang á» Äây"105 }106 };107 $scope.$apply();108 };109 //110 // Show search location111 var setSearchingLocation = function (coords) {112 $scope.map.center = { latitude: coords.latitude, longitude: coords.longitude };113 $scope.searchingLocation = {114 id: -2,115 latitude: coords.latitude,116 longitude: coords.longitude,117 address: coords.address, // From Google Place API118 photos: coords.photos, // From Google Place API119 title: 'Di chuyá»n Äá» tìm bãi Äáºu xe',120 options: {121 //icon: image,122 draggable: true,123 animation: 0,124 label: "",125 title: "Di chuyá»n Äá» tìm bãi Äáºu xe"126 },127 infoWindow: {128 options: {129 boxClass: 'current-location-info-window',130 closeBoxDiv: '<div" class="pull-right" style="position: relative; cursor: pointer; margin: -20px -15px;">X</div>',131 disableAutoPan: true,132 },133 show: false134 },135 events: {136 dragend: function (e, name, marker) {137 console.log("dragend", e, marker);138 if (e && e.position) {139 $scope.searchProviders({ "latitude": e.position.lat(), "longitude": e.position.lng() });140 }141 },142 click: function (e, name, marker) {143 $scope.showProviderDetailPopup(marker);144 },145 mouseout: function (e, name, marker) {146 //console.log("mouseout", e, marker);147 },148 mouseover: function (e, name, marker) {149 //console.log("mouseover", e, marker);150 }151 }152 };153 $scope.$apply();154 };155 156 //157 // Clear direction on the map158 $scope.clearDirections = function() {159 if ($scope.directionsDisplay)160 $scope.directionsDisplay.setMap(null);161 };162 //163 // Show the direction between 2 locations164 $scope.showDirection = function(origin, destination) {165 var deferred = $q.defer();166 $scope.clearDirections();167 $scope.showList = false;168 if (origin && destination) {169 $scope.directionsDisplay = new google.maps.DirectionsRenderer({170 map: $scope.mapInstance,171 draggable: true,172 suppressMarkers: true // Disable A & B marker173 });174 $scope.directionsService = new google.maps.DirectionsService();175 // Set destination, origin and travel mode.176 var request = {177 destination: { lat: destination.latitude, lng: destination.longitude },178 origin: { lat: origin.latitude, lng: origin.longitude },179 travelMode: google.maps.TravelMode.DRIVING180 };181 // Pass the directions request to the directions service.182 $scope.directionsService.route(request, function(response, status) {183 if (status == google.maps.DirectionsStatus.OK) {184 // Display the route on the map.185 $scope.directionsDisplay.setDirections(response);186 //187 // Repaint gmap188 setTimeout(function() {189 window.dispatchEvent(new Event('resize'));190 }, 500); // Delay for animation of the map.191 deferred.resolve(response);192 } else {193 deferred.reject(response);194 }195 });196 } else {197 deferred.reject("Missing origin or destination");198 }199 return deferred.promise;200 };201 //202 // Show the direction from current location to another location203 $scope.directTo = function (destination) {204 var loc = $scope.currentLocation ? $scope.currentLocation : $scope.searchingLocation;205 $scope.showDirection(loc, destination).then(function(data) {206 if ($scope.searchingLocation && data && data.routes && data.routes[0] && data.routes[0].legs && data.routes[0].legs[0]) {207 // Show distance in case of the distance of Searching Location and Current Location is lower than 100 met.208 if (baseService.getDistanceFromLatLng($scope.searchingLocation, $scope.currentLocation) > 0.1) {209 destination.direction = {210 "distance": data.routes[0].legs[0].distance,211 "duration": data.routes[0].legs[0].duration212 };213 }214 }215 });216 };217 //218 // Use google api to get the distances to provider locations219 var getDistances = function (origins, destinations) {220 var deferred = $q.defer();221 if (origins && origins.length > 0 && destinations && destinations.length > 0) {222 var mapOrigins = [], mapDestinations = [], i;223 for (i = 0; i < origins.length; i++)224 mapOrigins.push(new google.maps.LatLng(origins[i].latitude, origins[i].longitude));225 for (i = 0; i < destinations.length; i++)226 mapDestinations.push(new google.maps.LatLng(destinations[i].latitude, destinations[i].longitude));227 var service = new google.maps.DistanceMatrixService();228 var options = {229 origins: mapOrigins,230 destinations: mapDestinations,231 travelMode: google.maps.TravelMode.DRIVING232 }233 service.getDistanceMatrix(options, function (response, status) {234 if (status === "OK") {235 deferred.resolve(response);236 } else {237 deferred.reject({ "error": "The distances aren't calculated." });238 }239 });240 } else {241 deferred.reject({ "error": "Missing origin or destination" });242 }243 return deferred.promise;244 };245 //246 // Sort the locations list247 var sortMapMarkers = function () {248 if ($scope.map.markers && $scope.map.markers.length > 0) {249 var sortField = "distance.value";250 var reverse = false;251 if ($scope.sortBy && $scope.sortBy.name) {252 if ($scope.sortBy.name === "lowPrice") {253 sortField = "provider.Price";254 }255 else if ($scope.sortBy.name === "highPrice") {256 sortField = "provider.Price";257 reverse = true;258 }259 }260 $scope.map.markers = $filter('orderBy')($scope.map.markers, sortField, reverse);261 }262 };263 264 //265 // Show Provider Details Popup266 $scope.showProviderDetailPopup = function (marker) {267 $mdDialog.show({268 data: { "marker": marker, "getDirection": function() { $scope.directTo(marker); } },269 controller: ProviderDetailsDialogController,270 templateUrl: '/App/views/provider/detail-dialog.html',271 parent: angular.element(document.body),272 //targetEvent: ev,273 clickOutsideToClose: true,274 fullscreen: window.outerWidth <= 550,275 });276 };277 //278 // Zoom to show all markers279 $scope.zoomMapToCoverAllMarkers = function () {280 if (!$scope.map.markers || $scope.map.markers.length === 0) {281 $scope.mapInstance.setZoom(14);282 return;283 }284 var bounds = new google.maps.LatLngBounds();285 for (var i = 0; i < $scope.map.markers.length; i++) {286 bounds.extend($scope.map.markers[i].getPosition());287 }288 //center the map to the geometric center of all markers289 $scope.mapInstance.setCenter(bounds.getCenter());290 //$scope.mapInstance.panTo(bounds.getCenter());291 $scope.mapInstance.fitBounds(bounds);292 // Remove one zoom level to ensure no marker is on the edge.293 if($scope.mapInstance.getZoom() < 10)294 $scope.mapInstance.setZoom($scope.mapInstance.getZoom() - 1);295 // Set a minimum zoom, if you got only 1 marker or all markers are on the same address map will be zoomed too much.296 if ($scope.mapInstance.getZoom() > 15) {297 $scope.mapInstance.setZoom(15);298 }299 //Alternatively this code can be used to set the zoom for just 1 marker and to skip redrawing.300 //Note that this will not cover the case if you have 2 markers on the same address.301 //if ($scope.map.markers.length === 1) {302 // $scope.mapInstance.setMaxZoom(15);303 // $scope.mapInstance.fitBounds(bounds);304 // $scope.mapInstance.setMaxZoom(null);305 //}306 };307 //308 // Search provider locations near current location309 $scope.searchProviders = function (coords) {310 $scope.loading = true;311 $scope.clearDirections();312 var dataToSend = {313 Latitude: coords.latitude,314 Longitude: coords.longitude,315 //Radius: $scope.Radius * 1000,316 Radius: $scope.slider.value317 };318 // Filter319 angular.forEach($scope.filterByItems, function (item, key) {320 if (item.name && item.name.length > 0)321 dataToSend[item.name] = true;322 });323 $scope.map.markers = [];324 parkingSlotService.searchProviders(dataToSend).then(325 function(data) {326 var markers = [];327 if (data && data.length > 0) {328 angular.forEach(data, function (provider, key) {329 // Events - Marker - Of Provider330 var events = { click: function(e, m) { $scope.showProviderDetailPopup(m); } };331 var marker = baseService.providerToMarker(provider, events);332 markers.push(marker);333 // Conver Datetime334 if (provider.AvailableFromTime)335 provider.AvailableFromTime = new Date(provider.AvailableFromTime);336 if (provider.AvailableToTime)337 provider.AvailableToTime = new Date(provider.AvailableToTime);338 });339 }340 $scope.map.markers = markers;341 //342 // Cover All Markers343 $scope.zoomMapToCoverAllMarkers();344 //345 // Get distances to providers346 var location = $scope.searchingLocation ? $scope.searchingLocation : $scope.currentLocation;347 if (location) {348 getDistances([location], $scope.map.markers).then(function (data) {349 if (data && data.rows && data.rows.length > 0) {350 var distances = data.rows[0].elements;351 if (distances.length === $scope.map.markers.length) {352 for (var i = 0; i < distances.length; i++) {353 if (distances[i].distance) {354 $scope.map.markers[i].distance = distances[i].distance;355 $scope.map.markers[i].distanceValue = distances[i].distance.value;356 }357 if (distances[i].duration)358 $scope.map.markers[i].duration = distances[i].duration;359 }360 //361 // Sort markers362 sortMapMarkers();363 }364 }365 });366 }367 $scope.loading = false;368 },369 function(status) {370 $scope.map.markers = [];371 $scope.loading = false;372 }373 );374 };375 //376 // Handle clear search term to perform first searching377 $scope.$on('clearSearchTerm', function (event, args) {378 $scope.searchingLocation = undefined;379 setTimeout(function() { setCurrentLocation($scope.currentLocation); });380 $scope.searchProviders($scope.currentLocation);381 });382 383 //384 // Google Map is ready385 uiGmapGoogleMapApi.then(function (maps, a, b, c) {386 var searchElement = document.getElementById('autocomplete');387 var autocomplete = new google.maps.places.Autocomplete((searchElement), { types: ['geocode'] });388 searchElement.placeholder = "";389 autocomplete.addListener('place_changed', function () {390 // Get the place details from the autocomplete object.391 var place = autocomplete.getPlace();392 if (place.geometry && place.geometry.location) {393 var coords = { latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() };394 395 coords.address = place.adr_address;396 coords.photos = place.photos;397 setSearchingLocation(coords);398 // Search slot providers 399 $scope.searchProviders(coords);400 }401 });402 });403 //404 // Handle sorting changed event405 $scope.$watch('sortBy', function (newValue, oldValue) {406 if (newValue.id !== oldValue.id) {407 console.log('sortBy changed', newValue, oldValue);408 sortMapMarkers();409 }410 });411 //412 // Handle filtering changed event413 $scope.$watch('filterByItems', function (newValue, oldValue) {414 if (newValue.length !== oldValue.length) {415 var location = $scope.searchingLocation ? $scope.searchingLocation : $scope.currentLocation;416 $scope.searchProviders(location);417 }418 });419 $scope.moveToCurrentLocation = function () {420 if ($scope.currentLocation) {421 $scope.map.center = { latitude: $scope.currentLocation.latitude, longitude: $scope.currentLocation.longitude };422 }423 else if (navigator.geolocation) {424 try {425 navigator.geolocation.getCurrentPosition(function (position) {426 setCurrentLocation(position.coords);427 // Search slot providers 428 $scope.searchProviders(position.coords);429 });430 } catch (e) {431 }432 }433 };434 $scope.getThumbnailImage = function (provider) {435 if (!provider || typeof (provider.ImageLocation1) !== "string")436 return "";437 return provider.ImageLocation1.replace("/ProviderImages/", "/ProviderImages/Thumbnail/");438 };439 });...
journal.js
Source:journal.js
1angular.module('bhima.controllers')2 .controller('JournalController', JournalController);3JournalController.$inject = [4 'JournalService', 'GridSortingService', 'GridGroupingService',5 'GridFilteringService', 'GridColumnService',6 'SessionService', 'NotifyService', 'TransactionService', 'GridEditorService',7 'bhConstants', '$state', 'uiGridConstants', 'ModalService', 'LanguageService',8 'AppCache', 'Store', 'uiGridGroupingConstants', 'ExportService', 'FindEntityService',9 '$rootScope', '$filter', '$translate', 'GridExportService', 'TransactionTypeService', 'GridStateService'10];11/**12 * @module JournalController13 *14 * @description15 * This controller is responsible for initialising the core client side posting16 * journal, binding the UI Grid component with services that facilitate all17 * operations required by an accountant.18 * - Displaying transactions in an easy to find and review format19 * - Search for transactions20 * - Filter transactions21 * - Group by transactions to show aggregates22 * - Sort transactions23 * - Show or hide columns24 *25 * - (Super user) Edit and update transactions26 * - Post one or more transactions to the general ledger to confirm they are complete27 * - Tun trial balance validation on transactions28 *29 * @todo Propose utility bar view design30 */31function JournalController(Journal, Sorting, Grouping,32 Filtering, Columns, Session, Notify, Transactions, Editors,33 bhConstants, $state, uiGridConstants, Modal, Languages, AppCache, Store,34 uiGridGroupingConstants, Export, FindEntity, $rootScope, $filter,35 $translate, GridExport, TransactionType, GridState) {36 // Journal utilities37 var sorting;38 var grouping;39 var filtering;40 var columnConfig;41 var transactions;42 var exportation;43 var state;44 /** @const the cache alias for this controller */45 var cacheKey = 'Journal';46 // top level cache47 var cache = AppCache(cacheKey + '-module');48 var vm = this;49 // number of all of the transactions in the system50 Journal.count()51 .then(function (data) {52 vm.numberTotalSystemTransactions = data[0].number_transactions;53 })54 .catch(function (error) {55 Notify.handleError(error);56 });57 /** @constants */58 vm.ROW_EDIT_FLAG = bhConstants.transactions.ROW_EDIT_FLAG;59 vm.ROW_HIGHLIGHT_FLAG = bhConstants.transactions.ROW_HIGHLIGHT_FLAG;60 vm.ROW_INVALID_FLAG = bhConstants.transactions.ROW_INVALID_FLAG;61 // @todo - this doesn't work with the ui-grid-datepicker-edit library yet.62 vm.DATEPICKER_OPTIONS = { format: bhConstants.dates.format };63 vm.enterprise = Session.enterprise;64 vm.languages = Languages;65 vm.gridApi = {};66 // gridOptions is bound to the UI Grid and used to configure many of the67 // options, it is also used by the grid to expose the API68 vm.gridOptions = {69 enableColumnMenus : false,70 showColumnFooter : true,71 appScopeProvider : vm,72 flatEntityAccess : true,73 enableGroupHeaderSelection : true,74 enableRowHeaderSelection : true,75 rowTemplate : '/modules/templates/grid/transaction.row.html',76 onRegisterApi : onRegisterApi,77 };78 vm.grouped = angular.isDefined(cache.grouped) ? cache.grouped : false;79 // Initialise each of the journal utilities, providing them access to the journal80 // configuration options81 sorting = new Sorting(vm.gridOptions);82 filtering = new Filtering(vm.gridOptions, cacheKey);83 grouping = new Grouping(vm.gridOptions, true, 'trans_id', vm.grouped, false);84 columnConfig = new Columns(vm.gridOptions, cacheKey);85 transactions = new Transactions(vm.gridOptions);86 exportation = new GridExport(vm.gridOptions, 'selected', 'visible');87 state = new GridState(vm.gridOptions, cacheKey);88 // attaching the filtering object to the view89 vm.filtering = filtering;90 // attaching the grouping object to the view91 vm.grouping = grouping;92 // Attaching the transaction to the view93 vm.transactions = transactions;94 vm.onRemoveFilter = onRemoveFilter;95 vm.cancelEdit = cancelEdit;96 97 /**98 * @function toggleLoadingIndicator99 *100 * @description101 * Toggles the grid's loading indicator to eliminate the flash when rendering102 * transactions and allow a better UX for slow loads.103 */104 function toggleLoadingIndicator() {105 vm.loading = !vm.loading;106 }107 vm.saveGridState = state.saveGridState;108 vm.clearGridState = function clearGridState() {109 state.clearGridState();110 $state.reload();111 };112 113 114 /**115 * Column definitions; specify the configuration and behaviour for each column116 * in the journal grid. Initialise each of the journal utilities,117 * providing them access to the journal118 * configuration options :119 * sorting = new Sorting(vm.gridOptions);120 * grouping = new Grouping(vm.gridOptions);121 * filtering = new Filtering(vm.gridOptions);122 *123 * Note:124 * 1. Setting the grouping priority without sorting by the same column will125 * cause unexpected behaviour (splitting up of groups) when sorting126 * other columns. This can be avoided by setting default sort and group.127 */128 var columns = [129 { field : 'uuid',130 displayName : 'TABLE.COLUMNS.ID',131 headerCellFilter : 'translate',132 visible : false,133 enableCellEdit : false },134 { field : 'project_name',135 displayName : 'TABLE.COLUMNS.PROJECT',136 headerCellFilter : 'translate',137 visible : false,138 enableCellEdit : false },139 { field : 'period_end',140 displayName : 'TABLE.COLUMNS.PERIOD',141 headerCellFilter : 'translate',142 cellTemplate : 'modules/templates/bhPeriod.tmpl.html',143 visible : false,144 enableCellEdit : false },145 { field : 'trans_id',146 displayName : 'TABLE.COLUMNS.TRANSACTION',147 headerCellFilter : 'translate',148 sortingAlgorithm : sorting.transactionIds,149 enableCellEdit : false,150 width : 110,151 cellTemplate : 'modules/journal/templates/hide-groups-label.cell.html' },152 { field : 'trans_date',153 displayName : 'TABLE.COLUMNS.DATE',154 headerCellFilter : 'translate',155 cellFilter : 'date:"' + bhConstants.dates.format + '"',156 filter : { condition: filtering.filterByDate },157 editableCellTemplate : 'modules/journal/templates/date.edit.html',158 treeAggregationType : uiGridGroupingConstants.aggregation.MIN,159 customTreeAggregationFinalizerFn : function (aggregation) {160 aggregation.rendered = $filter('date')(aggregation.value, bhConstants.dates.format);161 },162 enableCellEdit : true,163 footerCellTemplate : '<i></i>' },164 { field : 'hrRecord',165 displayName : 'TABLE.COLUMNS.RECORD',166 headerCellFilter : 'translate',167 visible : true,168 treeAggregationType : uiGridGroupingConstants.aggregation.MIN,169 treeAggregationLabel : '',170 enableCellEdit : false,171 footerCellTemplate : '<i></i>' },172 { field : 'description',173 displayName : 'TABLE.COLUMNS.DESCRIPTION',174 headerCellFilter : 'translate',175 footerCellTemplate : '<i></i>' },176 { field : 'account_number',177 displayName : 'TABLE.COLUMNS.ACCOUNT',178 editableCellTemplate : '<div><form name="inputForm"><div ui-grid-edit-account></div></form></div>',179 enableCellEdit : true,180 cellTemplate : '/modules/journal/templates/account.cell.html',181 headerCellFilter : 'translate',182 }, {183 field : 'debit_equiv',184 displayName : 'TABLE.COLUMNS.DEBIT',185 headerCellFilter : 'translate',186 treeAggregationType : uiGridGroupingConstants.aggregation.SUM,187 customTreeAggregationFinalizerFn : function (aggregation) {188 aggregation.rendered = aggregation.value;189 },190 enableFiltering : true,191 footerCellFilter : 'currency:grid.appScope.enterprise.currency_id'192 },193 { field : 'credit_equiv',194 displayName : 'TABLE.COLUMNS.CREDIT',195 headerCellFilter : 'translate',196 treeAggregationType : uiGridGroupingConstants.aggregation.SUM,197 customTreeAggregationFinalizerFn : function (aggregation) {198 aggregation.rendered = aggregation.value;199 },200 enableFiltering : true,201 footerCellFilter : 'currency:grid.appScope.enterprise.currency_id'202 },203 { field : 'currencyName',204 displayName : 'TABLE.COLUMNS.CURRENCY',205 headerCellFilter : 'translate',206 visible : false,207 enableCellEdit : false },208 { field : 'debit',209 displayName : 'TABLE.COLUMNS.DEBIT_SOURCE',210 headerCellFilter : 'translate',211 visible : false,212 cellTemplate : '/modules/journal/templates/debit.grid.html',213 enableCellEdit : false },214 { field : 'credit',215 displayName : 'TABLE.COLUMNS.CREDIT_SOURCE',216 headerCellFilter : 'translate',217 visible : false,218 cellTemplate : '/modules/journal/templates/credit.grid.html',219 enableCellEdit : false },220 { field : 'hrEntity',221 displayName : 'TABLE.COLUMNS.RECIPIENT',222 headerCellFilter : 'translate',223 editableCellTemplate : '/modules/journal/templates/entity.edit.html',224 visible : true },225 { field : 'hrReference',226 displayName : 'TABLE.COLUMNS.REFERENCE',227 cellTemplate : '/modules/journal/templates/references.link.html',228 headerCellFilter : 'translate',229 visible : true },230 { field : 'origin_id',231 displayName : 'FORM.LABELS.TRANSACTION_TYPE',232 headerCellFilter : 'translate',233 cellTemplate : '/modules/journal/templates/transaction_type.html',234 editableCellTemplate : '/modules/journal/templates/transaction_type.edit.html',235 visible : false },236 { field : 'display_name',237 displayName : 'TABLE.COLUMNS.RESPONSIBLE',238 headerCellFilter : 'translate',239 visible : false,240 enableCellEdit : false },241 { field : 'actions',242 displayName : '',243 headerCellFilter : 'translate',244 visible : true,245 enableCellEdit : false,246 cellTemplate : '/modules/journal/templates/actions.cell.html',247 allowCellFocus : false,248 enableFiltering : false,249 },250 ];251 vm.gridOptions.columnDefs = columns;252 // API register function253 function onRegisterApi(gridApi) {254 vm.gridApi = gridApi;255 vm.gridApi.edit.on.afterCellEdit(null, function (rowEntity, colDef, newValue, oldValue) {256 if (newValue != oldValue) {257 propagate(colDef.field, newValue);258 }259 });260 }261 function updateSharedPropertyOnRow(rows, column, value) {262 rows.forEach(function (row) {263 transactions.editCell(row, column, value, row[column]);264 row[column] = (column === 'trans_date') ? new Date(value) : value;265 });266 }267 function propagate(column, value){268 var propagateColumn = ['trans_date', 'entity_uuid', 'origin_id'];269 // Check if the column updated must be propragated in all transaction270 var hasSharedProperty = propagateColumn.indexOf(column) !== -1;271 if (hasSharedProperty) {272 // pass updates on to both the original rows and the new (pending) rows273 updateSharedPropertyOnRow(vm.transactions._entity.data.data, column, value);274 updateSharedPropertyOnRow(vm.transactions._entity.newRows.data, column, value);275 }276 }277 // This function opens a modal through column service to let the user show or Hide columns278 vm.openColumnConfigModal = function openColumnConfigModal() {279 // column configuration has direct access to the grid API to alter the current280 // state of the columns - this will be saved if the user saves the grid configuration281 columnConfig.openConfigurationModal();282 };283 // This function opens a modal, to let the user posting transaction to the general ledger284 vm.openTrialBalanceModal = function openTrialBalanceModal() {285 var numberSelectedGroup = vm.grouping.getSelectedGroups().length;286 // make sure a row is selected before running the trial balance287 if (numberSelectedGroup === 0) {288 Notify.warn('POSTING_JOURNAL.WARNINGS.NO_TRANSACTIONS_SELECTED');289 return;290 }291 $state.go('trialBalanceMain', { records : vm.grouping.getSelectedGroups() });292 };293 // format Export Parameters294 function formatExportParameters(type) {295 // make sure a row is selected before running the trial balance296 if (grouping.selectedRowCount < 1) {297 Notify.warn('POSTING_JOURNAL.WARNINGS.NO_TRANSACTIONS_SELECTED');298 return;299 }300 var uuids = vm.grouping.getSelectedGroups().map(function (trans) {301 return trans.uuid;302 });303 return { renderer: type || 'pdf', lang: Languages.key, uuids: uuids };304 }305 // display the journal printable report of selected transactions306 vm.openJournalReport = function openJournalReport() {307 var url = '/reports/finance/journal';308 var params = formatExportParameters('pdf');309 if (!params) { return; }310 Modal.openReports({ url: url, params: params });311 };312 // export data into csv file313 vm.exportFile = function exportFile() {314 exportation.run();315 };316 function errorHandler(error) {317 vm.hasError = true;318 Notify.handleError(error);319 }320 // loads data for the journal321 function load(options) {322 vm.loading = true;323 vm.hasError = false;324 vm.gridOptions.gridFooterTemplate = null;325 vm.gridOptions.showGridFooter = false;326 // @fixme327 Journal.grid(null, options)328 .then(function (records) {329 // number of transactions downloaded and shown in the current journal330 vm.numberCurrentGridTransactions = records.aggregate.length;331 // pre process data - this should be done in a more generic way in a service332 vm.gridOptions.data = transactions.preprocessJournalData(records);333 vm.gridOptions.showGridFooter = true;334 vm.gridOptions.gridFooterTemplate = '/modules/journal/templates/grid.footer.html';335 transactions.applyEdits();336 // @TODO investigate why footer totals aren't updated automatically on data change337 vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL);338 })339 .catch(errorHandler)340 .finally(toggleLoadingIndicator);341 }342 // this method can eventually ensure we have a flat direct binding to all343 // cells in UI grid. This should drastically improve performance344 // @todo move this method into a service345 function preprocessJournalData(data) {346 var aggregateStore = new Store({ identifier: 'record_uuid' });347 aggregateStore.setData(data.aggregate);348 data.journal.forEach(function (row) {349 // give each row a reference to its transaction aggregate data350 row.transaction = aggregateStore.get(row.record_uuid);351 });352 return data.journal;353 }354 // open search modal355 vm.openSearchModal = function openSearchModal() {356 var filtersSnapshot = Journal.filters.formatHTTP();357 Journal.openSearchModal(filtersSnapshot)358 .then(function (changes) {359 Journal.filters.replaceFilters(changes);360 Journal.cacheFilters();361 vm.latestViewFilters = Journal.filters.formatView();362 toggleLoadingIndicator();363 return load(Journal.filters.formatHTTP(true));364 })365 .catch(angular.noop);366 };367 // remove a filter with from the filter object, save the filters and reload368 function onRemoveFilter(key) {369 Journal.removeFilter(key);370 Journal.cacheFilters();371 vm.latestViewFilters = Journal.filters.formatView();372 return load(Journal.filters.formatHTTP(true));373 }374 vm.editTransaction = editTransaction;375 function editTransaction(row) {376 vm.filterBarHeight = bhConstants.utilBar.journalHeightStyle;377 // expand the row378 vm.grouping.unfoldGroup(row);379 transactions.edit(row);380 // disable inline filtering when editing381 filtering.disableInlineFiltering();382 }383 vm.saveTransaction = saveTransaction;384 function saveTransaction() {385 vm.filterBarHeight = bhConstants.utilBar.collapsedHeightStyle;386 transactions.save()387 .then(function (results) {388 Notify.success('POSTING_JOURNAL.SAVE_TRANSACTION_SUCCESS');389 // ensure that all of the data now respects the current filter390 load(Journal.filters.formatHTTP(true));391 })392 .catch(function (error) {393 if (!error.status) {394 Notify.warn(error);395 } else {396 Notify.handleError(error);397 }398 });399 }400 vm.toggleTransactionGroup = function toggleTransactionGroup() {401 var transactionColumnKey = 'trans_id';402 // column grouping is permenantly saved if the user saves the current grid state403 if (vm.grouping.getCurrentGroupingColumn()) {404 // grid is currently grouped - toggle should remove the grouping405 vm.grouping.removeGrouping(transactionColumnKey);406 return;407 }408 // grid is not currently grouped - toggle should group on the trans_id column409 vm.grouping.changeGrouping(transactionColumnKey);410 };411 // @TODO this method is called on every single digest to determine if the grid is412 // currently grouped - this should only be called once on grid load and then413 // updated to keep track of the current grid grouped state414 vm.gridGroupedState = vm.grouping.getCurrentGroupingColumn;415 vm.saveAccountEdit = function saveAccountEdit(row, account) {416 row.account_id = account.id;417 row.account_name = account.hrlabel;418 $rootScope.$emit(uiGridEditConstants.events.END_CELL_EDIT);419 };420 function cancelEdit() {421 vm.filterBarHeight = bhConstants.utilBar.collapsedHeightStyle;422 // @TODO this should return a promise in a uniform standard with `saveTransaction`423 transactions.cancel();424 // ensure data that has been changed is up to date from the server425 // remove any additional or temporary rows426 load(Journal.filters.formatHTTP(true));427 }428 // runs on startup429 function startup() {430 load(Journal.filters.formatHTTP(true));431 vm.latestViewFilters = Journal.filters.formatView();432 loadTransactionType();433 }434 // ===================== edit entity ===============================435 // expose to the view436 vm.openEntityModal = openEntityModal;437 vm.removeEntity = removeEntity;438 // open find entity modal439 function openEntityModal(row) {440 FindEntity.openModal()441 .then(function (entity) {442 if (!entity) { return; }443 row.hrEntity = entity.hrEntity;444 transactions.editCell(row, 'entity_uuid', entity.uuid);445 });446 }447 // remove the entity448 function removeEntity(row) {449 if (!row.hrEntity) { return; }450 transactions.editCell(row, 'entity_uuid', null);451 delete row.entity_uuid;452 delete row.hrEntity;453 }454 // ===================== end edit entity ===========================455 // ===================== transaction type ==========================456 vm.editTransactionType = editTransactionType;457 vm.removeTransactionType = removeTransactionType;458 // edit transaction type459 function editTransactionType(row) {460 var id = row.origin_id;461 transactions.editCell(row, 'origin_id', id);462 // Propagate the change in all origin Id for transaction463 propagate('origin_id', id);464 }465 // remove transaction type466 function removeTransactionType(row) {467 transactions.editCell(row, 'origin_id', null);468 }469 // load transaction types470 function loadTransactionType() {471 TransactionType.read()472 .then(function (list) {473 vm.mapOrigins = {};474 vm.typeList = list.map(function (item) {475 item.hrText = $translate.instant(item.text);476 vm.mapOrigins[item.id] = item.hrText;477 return item;478 });479 })480 .catch(Notify.handleError);481 }482 // ===================== end transaction type ======================483 startup();...
TextEditor.js
Source:TextEditor.js
...125 })126 return (127 <div className="c-item">128 {129 mapOrigins(transformedLinks)130 }131 </div>132 )133 }134 135 if ( !links.length && !isEmpty ) {136 return (137 <div className="c-inital">138 Select a Section and Press <em>Ctrl+H</em> to analyse139 </div>140 )141 }142 return (143 <div className="c-inital">...
popup.js
Source:popup.js
...68 </div>69 )70}71function Main() {72 const origins = mapOrigins(localStore.bookmarks)73 const { origin } = localStore74 return (75 <div className="">76 {!origins.includes(origin) && <AddBookmark />}77 <Bookmarks />78 </div>79 )80}81function Footer() {82 const settingsUrl = chrome.runtime.getURL('options.html')83 return (84 <div className="text-center">85 <a className="text-blue-500 text-sm" href={settingsUrl} target="_blank">Settings</a>86 </div>...
background.js
Source:background.js
...34 WARN_ON_NEW_FORM_PAGE,35 WARN_ON_EVERY_FORM_PAGE,36 BOOKMARKS,37 ], ({warnOnNewSite, warnOnNewFormPage, warnOnEveryFormPage, bookmarks}) => {38 if(mapOrigins(bookmarks).includes(getOrigin(origin))) {39 tickIcon(tabId)40 return41 }42 // user visits a login page for the first time43 chrome.history.getVisits({url}, (visits) => {44 if(warnOnNewFormPage && visits.length === 1 && pwdFieldCount > 0) {45 return openWarningPage({pwdFieldCount, origin, type: WARN_ON_NEW_FORM_PAGE})46 }47 chrome.history.search({text: origin, startTime: 0, maxResults: 99999}, (visits) => {48 const trueVisits = filterByOrigin({origin, visits})49 // user visits a site for the first time50 if(warnOnNewSite && trueVisits.length === 1) {51 return openWarningPage({pwdFieldCount, origin, type: WARN_ON_NEW_SITE})52 }53 if(warnOnEveryFormPage && pwdFieldCount > 0) {54 return openWarningPage({pwdFieldCount, origin, type: WARN_ON_EVERY_FORM_PAGE})55 }56 })57 })58 })59}60chrome.runtime.onMessage.addListener(61 function(request, sender) {62 if(!sender.tab) return63 const { url, origin } = sender64 const { pwdFieldCount } = request65 const { id: tabId } = sender.tab66 checkPhishing({url, origin, pwdFieldCount, tabId})67 }68)69chrome.tabs.onActivated.addListener(function(activeInfo) {70 chrome.storage.sync.set({[ACTIVE_TAB]: activeInfo})71})72chrome.storage.onChanged.addListener(() => {73 chrome.storage.sync.get([74 BOOKMARKS,75 ACTIVE_TAB76 ], ({bookmarks, activeTab}) => {77 chrome.tabs.query({'active': true}, function(tabs) {78 const {id, url} = tabs[0]79 if(mapOrigins(bookmarks).includes(getOrigin(url))) {80 tickIcon(id)81 }82 else {83 setDefaultIcon(id)84 }85 })86 })...
originCalculator.js
Source:originCalculator.js
...46 offset,47 morph48 )49 const firstOrigin = orientate(morph(textboxOrigin));50 const mapToBox = mapOrigins(firstOrigin);51 const textOrigins = mapToBox(textGrid);52 const dividerOrigins = mapToBox(dividerGrid);53 const newMaskOrigin = orientateMask(maskOrigin)54 return (55 Object.assign({},56 {...props},57 { transforms: transforms },58 { textOrigins: textOrigins },59 { dividerOrigins: dividerOrigins },60 { maskOrigin: newMaskOrigin }61 )62 )...
misc.js
Source:misc.js
...5 return visits.filter(({url}) => {6 return RegExp(`^${origin}`).test(url)7 })8}9export function mapOrigins(bookmarks) {10 return bookmarks.map(bookmark => bookmark.origin)11}12export function tickIcon(tabId) {13 chrome.browserAction.setIcon({14 path: '/images/tick-16.png',15 tabId16 })17}18export function setDefaultIcon(tabId) {19 chrome.browserAction.setIcon({20 path: '/images/Icon-16.png',21 tabId22 })23}
Using AI Code Generation
1describe('My First Test', () => {2 it('Visits the Kitchen Sink', () => {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1describe('My First Test', () => {2 it('Does not do much!', () => {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1Cypress.on("window:before:load", win => {2 win.fetch = null;3});4Cypress.on("window:before:load", win => {5 win.fetch = null;6});7Cypress.on("window:before:load", win => {8 win.fetch = null;9});10Cypress.on("window:before:load", win => {11 win.fetch = null;12});13Cypress.on("window:before:load", win => {14 win.fetch = null;15});16Cypress.on("window:before:load", win => {17 win.fetch = null;18});19Cypress.on("window:before:load", win => {20 win.fetch = null;21});22Cypress.on("window:before:load", win => {23 win.fetch = null;24});25Cypress.on("window:before:load", win => {26 win.fetch = null;27});28Cypress.on("window:before:load", win => {29 win.fetch = null;30});31Cypress.on("window:before:load", win => {32 win.fetch = null;33});34Cypress.on("window:before:load", win => {35 win.fetch = null;36});37Cypress.on("window:before:load", win => {38 win.fetch = null;39});40Cypress.on("window:before:load", win => {41 win.fetch = null;42});43Cypress.on("window:before:load", win => {44 win.fetch = null;45});46Cypress.on("window:before:
Using AI Code Generation
1cy.location('pathname').should('include', 'commands/location')2cy.location('hash').should('be.empty')3cy.location('search').should('be.empty')4cy.mapOrigins({5})6cy.location('pathname').should('include', 'commands/location')7cy.location('hash').should('be.empty')8cy.location('search').should('be.empty')9cy.mapOrigins({10})11cy.location('pathname').should('include', 'commands/location')12cy.location('hash').should('be.empty')13cy.location('search').should('be.empty')14cy.mapOrigins()15cy.location('pathname').should('include', 'commands/location')16cy.location('hash').should('be.empty')17cy.location('search').should('be.empty')18cy.mapOrigins({19})20cy.location('pathname').should('include', 'commands/location')21cy.location('hash').should('be.empty')22cy.location('search').should('be.empty')23cy.mapOrigins()
Using AI Code Generation
1Cypress.on('window:before:load', win => {2 win.fetch = null;3});4Cypress.on('window:before:load', win => {5 win.fetch = null;6});7Cypress.on('window:before:load', win => {8 win.fetch = null;9});10Cypress.on('window:before:load', win => {11 win.fetch = null;12});13Cypress.on('window:before:load', win => {14 win.fetch = null;15});16Cypress.on('window:before:load', win => {17 win.fetch = null;18});19Cypress.on('window:before:load', win => {20 win.fetch = null;21});22Cypress.on('window:before:load', win => {23 win.fetch = null;24});25Cypress.on('window:before:load', win => {26 win.fetch = null;27});28Cypress.on('window:before:load', win => {29 win.fetch = null;30});31Cypress.on('window:before:load', win => {32 win.fetch = null;33});34Cypress.on('window:before:load', win => {35 win.fetch = null;36});37Cypress.on('window:before:load', win => {38 win.fetch = null;39});40Cypress.on('window:before:load', win => {41 win.fetch = null;42});
Using AI Code Generation
1describe('Test', () => {2 it('should work', () => {3 cy.server();4 cy.route('GET', 'comments/*').as('getComment');5 cy.get('.network-btn').click();6 cy.wait('@getComment').then((xhr) => {7 cy.wrap(xhr).its('response.body').should('include', { id: 1, name: 'Using POST in cy.route()' });8 });9 });10});11Cypress. mapOrigins ( origin , destination )12Cypress. map ( origin , destination )13Cypress. map ( '/api/' , '/api/' )14Cypress has a method called unmap() which is used to unmap a path. This is useful to use when we want to unmap a path
Using AI Code Generation
1describe('Cypress mapOrigins', () => {2 it('should map origins', () => {3 cy.mapOrigins({4 })5 })6})7Cypress.Commands.add('mapOrigins', (origins) => {8 cy.window().then((win) => {9 const { Cypress } = win10 Cypress.on('window:before:load', (win) => {11 })12 Cypress.env('origins', origins)13 })14})15module.exports = (on, config) => {16 on('before:browser:launch', (browser = {}, args) => {17 if (browser.name === 'chrome') {18 args.push('--disable-web-security')19 }20 })21 on('task', {22 getOrigins() {23 return Cypress.env('origins')24 },25 })26}27Cypress.Commands.add('mapOrigins', (origins) => {28 cy.window().then((win) => {29 const { Cypress } = win30 Cypress.on('window:before:load', (win) => {31 })32 Cypress.env('origins', origins)33 })34})35const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin')36module.exports = (on, config) => {37 addMatchImageSnapshotPlugin(on, config)38 on('task', {39 getOrigins() {40 return Cypress.env('origins')41 },42 })43}44{
Using AI Code Generation
1describe('Map Origins', function() {2 it('Maps Origins', function() {3 cy.window().then(win => {4 win.mapOrigins()5 })6 })7})8Cypress.Commands.add('mapOrigins', () => {9 cy.window().then(win => {10 win.mapOrigins()11 })12})13import './commands'14Cypress.on('window:before:load', win => {15 win.mapOrigins = () => {16 const isOriginAllowed = origin => {17 return origins.includes(origin)18 }19 win.postMessage = message => {20 const { data, origin } = message21 if (!isOriginAllowed(origin)) {22 }23 win.MessageEvent('message', { data, origin })24 }25 }26})27describe('Map Origins', function() {28 it('Maps Origins', function() {29 cy.mapOrigins()30 })31})32describe('Map Origins', function() {33 it('Maps Origins', function() {34 cy.window().then(win => {35 win.mapOrigins()36 })37 })38})39describe('Map Origins', function() {40 it('Maps Origins', function() {41 cy.window().then(win => {42 win.mapOrigins()43 })44 })45})46describe('Map Origins', function() {47 it('Maps Origins', function() {48 cy.window().then(win => {49 win.mapOrigins()50 })51 })52})53describe('Map Origins', function() {54 it('Maps Origins', function() {55 cy.window().then(win => {56 win.mapOrigins()57 })58 })59})60describe('Map Origins',
Using AI Code Generation
1Cypress.on('window:before:load', win => {2})3Cypress.on('window:load', win => {4})5describe('Cypress Map Origins', () => {6 beforeEach(() => {7 })8 it('should map origins', () => {9 })10})11Cypress.on('window:before:load', win => {12})13Cypress.on('window:load', win => {14})15describe('Cypress Map Origins', () => {16 beforeEach(() => {17 cy.mapOrigins(18 {
Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!