I have a method in utils file that is commented like this, the body is not important.
/**
* Calculates width of the column.
*
* #param {string} text text.
* #param {boolean} hasTooltip does title have tooltip?
* #return {number} width of the column.
*/
const getColumnWidth = (text, hasTooltip) => {
const padding = 8;
const tooltipWidth = hasTooltip ? 22 : 0;
const sortArrowWidth = 26;
const context = document.createElement('canvas').getContext('2d');
context.font = getComputedStyle(document.body).font;
return context.measureText(text).width + padding + tooltipWidth + sortArrowWidth;
}
export {
...
getColumnWidth
};
Then this method is imported in another file.
import {
...
getColumnWidth
} from "c/dceSoftwareUtils";
The problem is when i use intellisense (ctrl + space) i see import instead of method comment:
But i need it to be displayed same way as getComputedStyle:
I believe this is caused by imported method being seen as property and not a method. How can i change this?
Related
I am trying to make something like Java's enum. It works perfectly, but when I try to compile it with ClosureCompiler, I get this warning:
F:\Site\_data\test-ccomp>ccomp -O ADVANCED --js source.js --js_output_file compiled.js
source.js:49:18: WARNING - [JSC_TYPE_MISMATCH] Can only iterate over a (non-null) Iterable type
found : (typeof Color)
required: Iterable
49| for( const clr of Color ) {
^^^^^
0 error(s), 1 warning(s), 87.2% typed
How to get rid of it? Which annotations to use?
If I make Color an object, not a function, with properties RED, GREEN, BLUE of some ColorObj type, and [Symbol.iterator] to iterate over them, it is still the same warning.
//////////////////
// Color type
//////////////////
/**
* For id generation.
*/
let color_counter = 0;
/**
* #constructor
* #param {string} txt Color name.
*/
function Color(txt) {
const id = color_counter++;
const text = txt;
this.ordinal = function() {
return id;
}
this.name = function() {
return text;
}
}
/**
* #const
* #type {Color}
*/
Color.BLUE = new Color("blue");
/**
* #const
* #type {Color}
*/
Color.RED = new Color("red");
/**
* #const
* #type {Color}
*/
Color.YELLOW = new Color("yellow");
/**
* What to annotate here for warning to go away?!
*/
Color[Symbol.iterator] = function*() {
yield Color.BLUE;
yield Color.RED;
yield Color.YELLOW;
}
///////////////////
// Test program
///////////////////
console.info("Colors:");
for (const clr of Color) {
console.info(" - " + clr.name());
}
console.info("Color.BLUE is " + Color.BLUE.name());
console.info("Color.RED is " + Color.RED.name());
I do have following Errors when js file is minified
/* Minification failed. Returning unminified contents.
(36307,7-8): run-time error JS1010: Expected identifier: .
(36307,7-8): run-time error JS1195: Expected expression: .
(36817,7-8): run-time error JS1010: Expected identifier: .
(36817,7-8): run-time error JS1195: Expected expression: .
(36820,7-8): run-time error JS1010: Expected identifier: .
(36820,7-8): run-time error JS1195: Expected expression: .
*/
The JavaScript file script file below,
However I found the JavaScript that contains "module.export"
will not be minified and I also use
online tool
for minification, but the minified file does not contain "module.export"
and it is removed
during minification. Any help how to sort the minification problem of JavaScript file contain module.export
(function e(t, n, r) {
module.exports = FilterCSS;
}, {
"./default": 7,
"./parser": 9,
"./util": 10
}], 7: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
function getDefaultWhiteList() {
// ??????:
// true: ?????
// Function: function (val) { } ??true???????,?????????
// RegExp: regexp.test(val) ??true???????,?????????
// ??????????????
var whiteList = {};
whiteList['align-content'] = false; // default: auto
whiteList['align-items'] = false; // default: auto
*
*
#param {
String
}
name
*
#param {
String
}
value
*
#param {
Object
}
options
*
#return {
String
}
*/
function onAttr(name, value, options) {
// do nothing
}
/**
* ???????????????
*
* #param {String} name
* #param {String} value
* #param {Object} options
* #return {String}
*/
function onIgnoreAttr(name, value, options) {
// do nothing
}
var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img;
/**
* ?????
*
* #param {String} name
* #param {String} value
* #return {String}
*/
function safeAttrValue(name, value) {
if (REGEXP_URL_JAVASCRIPT.test(value)) return '';
return value;
}
exports.whiteList = getDefaultWhiteList();
exports.getDefaultWhiteList = getDefaultWhiteList;
exports.onAttr = onAttr;
exports.onIgnoreAttr = onIgnoreAttr;
exports.safeAttrValue = safeAttrValue;
}, {}], 8: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
var DEFAULT = require('./default');
var FilterCSS = require('./css');
/**
* XSS??
*
* #param {String} css ????CSS??
* #param {Object} options ??:whiteList, onAttr, onIgnoreAttr
* #return {String}
*/
function filterCSS(html, options) {
var xss = new FilterCSS(options);
return xss.process(html);
}
// ??
exports = module.exports = filterCSS;
exports.FilterCSS = FilterCSS;
for (var i in DEFAULT) exports[i] = DEFAULT[i];
// ???????
if (typeof window !== 'undefined') {
window.filterCSS = module.exports;
}
}, {
"./css": 6,
"./default": 7
}], 9: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
var _ = require('./util');
Try like this:
['module'].exports = FilterCSS;
Also this:
[module].exports = FilterCSS;
It worked for me, but no idea why.
Before this epiphany, I had solve similar issues with global variables, using something like this:
window['module'].exports=......
But, at least in my case, module was no global.
No idea how I came up with this, and less idea how it worked. I'm new with javascript.
I have file in javascript i am opening using
fs.readFileSync(fileName)
after I return it to the client it is stored like so:
[G]Hey, where did [C]we go, da[G]ys when the ra[D]ins came
[G]Down in the holl[C]ow, [G]playin' a ne[D]w game
However, I need the x and y coordinates so that I can update my canvas.
Is there any way to do this?
If we assume the first character has the position {x: 0, y: 0} and that the next line increments the y position by one, then we can use something like this to calculate the positions of the characters:
/**
* Find the XY positions of this string
*
* #type {string}
*/
const given = `[G]Hey, where did [C]we go, da[G]ys when the ra[D]ins came
[G]Down in the holl[C]ow, [G]playing a ne[D]w game`;
/**
* Return the coordinates of the characters in a string
*
* #param {string} string
* #returns {Array}
*/
const calculateXY = (string) => {
const positions = [];
let yIndex = 0;
let xIndex = 0;
string.split('').forEach(character => {
if(/\n/g.test(character)) {
yIndex++;
xIndex = 0;
} else {
positions.push({ [character]: { x: xIndex, y: yIndex}});
}
xIndex++;
});
return positions;
};
const result = calculateXY(given);
console.log(result);
You can modify the above block an pass a multiplier so that x and y are incremented by the distance in pixels to the next character.
Resume: I'm currently writting an ActionScript 3 lexer that transforms a source code into tokens. I chosen to interpret the input, a String with optional surrogate pairs wrapped in a class UString, by code points. Under the hood I cache the last read position by using the UStringPos class.
I've tested how it scans the identifier "huehuehue" with...
'use strict';
import {Lexer} from 'core/Lexer';
import {UString} from 'utils/UString';
import ErrorHandler from 'core/ErrorHandler';
const errorHandler = new ErrorHandler(true);
// Tell the length to the `Lexer` manually.
const lexer = new Lexer(
new UString('huehuehue'), 9, errorHandler);
// Scan first token
lexer.next();
const id = lexer.lookahead.value;
console.log(
id,
id.length
);
It should have logged "huehuehue", 9, but was another story...
Why is it missing the last 'e'? The innermost method related on scanning this is Lexer#getCommonIdentifier. I've already tested my UString part and it works okay, by the way.
Lexer Related Definitions
/*
* Class that turns AS3 code into tokens.
*/
export class Lexer
{
/*
* #param {UString} source
* #param {Number} length
* #param {ErrorHandler} errorHandler
*/
constructor(source, length, errorHandler)
{
this.source = source;
this.length = length;
this.index = 0;
this.lineStart = 0;
this.lineNumber = 1;
this.comments = [];
this.errorHandler = errorHandler;
this.previousToken = null;
this.token = null;
this.lookahead = null;
this._special = [];
}
/*
* Verifies the end of file.
*/
eof()
{
return this.index >= this.length;
}
/*
* Advance the previous, current and lookahead tokens.
* The lexer however does not depend on these tokens.
*/
next()
{
this.previousToken = this.token;
this.token = this.lookahead;
this.lookahead = this.lex();
}
/*
* Consumes the next token and return it.
*/
lex()
{
this.consumeWhiteSpaces();
while (this.consumeComment())
this.consumeWhiteSpaces();
let cp = this.source.codePointAt(this.index);
let pureIdentifier =
Character.isIdentifierStart(cp);
if (pureIdentifier || (cp === 0x5C))
return this.scanIdentifierOrKeyword(!pureIdentifier);
if (this.eof())
{
let loc = [ this.index, this.lineNumber ];
return new Token(TokenType.EOF, loc, loc, '<end>');
}
}
/*
* Scan an identifier, keyword or boolean literal.
*/
scanIdentifierOrKeyword(usingEscape)
{
const start = this.index;
let id;
/* Like Esprima does: only identifiers containing
* escapes need some overheads. */
if (usingEscape)
{
id = this.getEscapedIdentifier(
String.fromCodePoint(this.scanUnicodeEscapeSequence()));
}
else
id = this.getCommonIdentifier();
return new Token(
TokenType.IDENTIFIER,
[ start , this.lineNumber ],
[ this.index, this.lineNumber ],
id
);
}
/*
* Interprets an identifier. If any escape appears, switches to
* getEscapedIdentifier().
*/
getCommonIdentifier()
{
const start = this.source.position.offset;
let cp = 0;
// Jump the starting symbol.
++this.index;
while (!this.eof())
{
cp = this.source.codePointAt(this.index);
if (Character.isIdentifierPart(cp))
++this.index;
// Switches to escape-minded task...
else if (cp === 0x5C)
return this.getUnicodeEscapedIdentifier(
this.source.string.slice(
start, this.source.position.offset
)
);
else break;
}
return this.source.string.slice(
start, this.source.position.offset
);
}
/* ... */
}
utils/UString.js
'use strict';
/*
* String wrapper with methods _based_ on code points.
*/
export class UString
{
/*
* Constructs the {UString}.
*
* #param {String} s String to be wrapped.
*/
constructor(s)
{
/*
* #type {String}
*/
this.string = s;
/*
* Tracks the last accessed position.
*
* #type {UStringPos}
*/
this.position = new UStringPos(0, 0);
}
/*
* Reads a code point at specific index.
*
* #param {Number} index
* #return {Number}
*/
codePointAt(index)
{
this.position.walk(this.string, index);
return this.string.codePointAt(this.position.offset);
}
/*
* Slices the internal string by code point indices.
*
* #param {Number} i
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, i);
i = this.position.offset;
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};
/*
* Class that tracks the position of a code point on a string.
*/
export class UStringPos
{
/*
* Constructs the {UStringPos}.
*
* #param {Number} index The initial index.
* #param {Number} offset The initial offset.
*/
constructor(index, offset)
{
/*
* #type {Number}
*/
this.index = index;
/*
* #type {Number}
*/
this.offset = offset;
}
/*
* Walks to the given index.
*
* #param {String} s
* #param {Number} index
* #note No backward. Track the previous position instead.
* #return {void}
*/
walk(s, index)
{
for (; this.index < index; ++this.index)
this.offset += (
this._usingSurrogates(
s.charCodeAt(this.offset)
) ? 2 : 1
);
}
/*
* #private
*/
_usingSurrogates(ch)
{
return (ch >= 0xD800) && (ch <= 0xDBFF);
}
};
Anything?
Okay. So it was a problem with this.source.position.offset: when I do ++this.index, the offset of my UStringPos doesn't update. The problem was with the slice thing.
this.source.string.slice(
start, this.source.position.offset
);
This slice was based on offsets, since I had to track the previous offset where the identifier started.
Solution
I can use the slice of my own UString class and use the first parameter as an offset and the last one as a normal index.
'use strict';
export class UString
{
// ...
/*
* Slices the internal string by using a pair of
* offset and code point indices.
*
* #param {Number} i Offset
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};
I would like to have a div act like a strobe light with jquery. Basicly change the background color from black to white every 500 milliseconds.
How can I do that?
<div id="strobe"></div>
Thank you!
The setInterval() function is your friend here.
You don't need to use JQuery, you can do it inn pure javascript - this is how you'd do it:
var elem = document.getElementById("strobe");
var strobeBackground = function() {
(elem.style.backgroundColor == "white") ? elem.style.backgroundColor = "black" : elem.style.backgroundColor = "white";
}
setInterval(strobeBackground, 500);
However if you want to do it in jQuery, here it is: http://jsfiddle.net/Ru9xt/2/
The HTML would look like this:
<div id="strobe" class="white">Hello</div>
The CSS would look like this:
.white {
background-color: white;
}
.black {
background-color: black;
}
And the JS is here:
setInterval(function () {
$("#strobe").toggleClass('black');
}, 500);
You can use jQuery for both checking the background color of the element and for setting the interval at which it flickers with the $.css() method which gets or sets the style of an element and the setInterval() method which sets up a reoccurring method call.
function toggle(){
var strobe = $('#strobe');
if(strobe.css('background-color') == '#FFFFFF'){
strobe.css('background-color', '#000000');
}else{
strobe.css('background-color', '#FFFFFF');
}
}
setInterval(toggle, 500);
I used classes instead:
/**
* Initialise strobe using classes. By Emmanuel Mahuni - 2015
* #param {string} sel selector
* #param {int} i speed in milli-seconds
* #param {string} c1 class 1
* #param {string} c2 class 2
* #returns {int} the interval id so that you can clear it later
*/
function initStrobeClass(sel, i, c1, c2) {
return setInterval(strobeClass, i,sel,c1,c2);
}
/**
* Strobe using classes. By Emmanuel Mahuni - 2015
* #param {string} sel selector
* #param {string} c1 class 1
* #param {string} c2 class 2
*/
function strobeClass(sel, c1, c2) {
var s = $(sel);
s.toggleClass(c1 + " " + c2);
}
/**
* Clear the strobe to a particular class
* #param {int} t interval id
* #param {string} sel selector of the element
* #param {string} c the class to set after clearing the strobe
* #returns {null} returns null to make sure we don't come back here again, make sure the interval id is set by this and do the checking to eliminate errors.
*/
function clearStrobeToClass(t, sel, c) {
clearInterval(t);
$(sel).attr('class', c);
return null;
}
usage:
The code below will begin strobbing the logout button when the count down is below 181. It will restore it when it goes above 180.
if (autoLogoutCountdown <= 180 && (typeof strobeLogoutTimer !== typeof NaN)) {
strobeLogoutTimer = initStrobeClass('#logout', 1000, 'logoutflash', 'logout');
} else if (autoLogoutCountdown > 180 && (typeof strobeLogoutTimer === typeof NaN)) {
strobeLogoutTimer = clearStrobeToClass(strobeLogoutTimer, '#logout', 'logout');
}
I hope this helps someone