How to define custom mode in ng2-codemirror? - javascript

I'd like to define my custom mode that extends one of available modes (e.g. javascript)? I've tried to use below code, but no effect.
CodeMirror.defineMode("foo", function (config, parserConfig) {
var fooOverlay = {
token: function (stream, state) {
var ch;
if (stream.match("{{")) {
while ((ch = stream.next()) != null)
if (ch == "}" && stream.next() == "}") {
stream.eat("}");
return "foo";
}
}
while (stream.next() != null && !stream.match("{{", false)) { }
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "javascript"), fooOverlay);
});
this.config = {
lineNumbers: true,
mode: 'foo'
};
UPDATE:
CodeMirror.defineSimpleMode("foo", {
start = [
{ regex: /"(?:[^\\]|\\.)*?(?:"|$)/, token: "string" },
{ regex: /'(?:[^\\]|\\.)*?(?:'|$)/, token: "string" },
{
regex: /(?:if|foreach|in|while)\b/,
token: "keyword"
},
{ regex: /true|false|null|undefined/, token: "atom" },
];
});

Related

Checking if there is a value in the Array hierarchy

I want to check if there is a value in a certain variable I have. Below I put an example of a logic that I want to achieve.
No matter how hard I tried, I was able to write a very sketchy code as a result of 3 hours of work and research, but it has nothing to do with what I want to achieve.
My Code:
const Files = [
{
Name: 'System',
Type: 'directory',
Value: [
{
Name: 'Main',
Type: 'directory',
Value: [
{
Name: 'Drivers',
Type: 'directory',
Value: [
{
Name: 'Startup',
Type: 'file',
Value: new FileSystem.File('Startup', 0x1, 'test blah blah'),
},
],
},
],
},
],
},
];
BlahBlah.has(Files, 'System->Main->Drivers');
// [File]
BlahBlah.has(Files, 'System->Main->Drivers->Startup');
// File
BlahBlah.has(Files, 'System->Main->Drivers->AnyWhere');
// undefined
BlahBlah.has(Files, 'System->Main->AnyRandomDirectory');
// NaN
My Function:
function text2Binary(str: string, spliter: string = ' '): string {
return str
.split('')
.map(function (char) {
return char.charCodeAt(0).toString(2);
})
.join(spliter);
}
export function FileTypeFromNumber(e: number) {
if (typeof e != 'number')
try {
e = Number(e);
} catch (_) {
return null;
}
return {
0x1: {
Name: 'Executable File',
Extension: 'exe',
},
0x2: {
Name: 'Text Document',
Extension: 'txt',
},
}[e];
}
export type FileTypes =
| 0x1
| 0x2
| 0x3
| 0x4
| 0x5
| 0x6
| 0x7
| 0x8
| 0x9
| null;
export class File {
Name: string;
Type: {
Name: string;
Extension: string;
};
Content: string;
Size: number;
constructor(name: string, type: FileTypes, content: string) {
this.Name = name;
this.Type = FileTypeFromNumber(type);
this.Content = content;
this.Size = text2Binary(content, '').length;
}
}
export class Directory {
public Name: string;
public Files: (File | Directory)[] = [];
constructor(name: string) {
this.Name = name;
}
addFile(file: File | Directory) {
this.Files.push(file);
}
getFile(name: string): null | (File | Directory)[] {
if (typeof name != 'string')
try {
name = String(name);
} catch (_) {
return null;
}
const Result = this.Files.filter((e) => e.Name == name);
return Result.length == 0 ? null : Result;
}
getSize() {
return this.Files.map((e) =>
e instanceof Directory ? e.getSize() : e.Size
).reduce((a, b) => a + b, 0);
}
has(name) {
return this.Files.some((e) => e.Name == name);
}
getJSON() {
return this.Files.map((e) => ({ ...e }));
}
}
interface x {
Content: string;
Name: string;
Size: number;
Type: string;
}
export function ConvertFromJSONtoDirectory(json: any[]) {
return json.map((value) => {
const isDirectory = value.Type == 'directory';
if (!isDirectory) {
return value.Value;
}
const self = new Directory(value.Name);
ConvertFromJSONtoDirectory(value.Value).map((e) => self.addFile(e));
return self;
});
}
export default class DirectorySystem {
Memory: Map<any, any>;
Current: string | null;
constructor(Current = null) {
this.Memory = new Map();
this.Current = Current;
}
addDirectory(directory: Directory): null | true {
if (!(directory instanceof Directory)) return null;
if (this.Memory.has(directory.Name)) return null;
this.Memory.set(directory.Name, directory);
return true;
}
getDirectory(DirectoryName: string): boolean | Directory {
if (typeof DirectoryName != 'string')
try {
DirectoryName = String(DirectoryName);
} catch (_) {
return null;
}
const Result = this.Memory.has(DirectoryName);
return Result ? this.Memory.get(DirectoryName) : Result;
}
getDirectoryCurrent() {
if (this.Current == null) return this;
}
changeDirectory(by: -1 | 1, value: string) {
if (by == -1) {
if (this.Current == null) return null;
if (this.Current.includes('->')) {
this.Current = this.Current.split('->').slice(0, -1).join('->');
} else {
this.Current = null;
}
return this.Current;
} else if (by == 1) {
let Position = [this.Current, value].join('->');
if (this.Current == null) {
Position = Position.split('->').slice(1).join('->');
}
let Result = this.has(Position);
console.log(Result);
}
}
has(query: string) {
try {
return query.split('->').reduce((a, b) => {
if (Array.isArray(a)) {
const f = a.filter((e) => e['Name'] == b);
if (a.length > 0) {
return f['Files'];
} else {
return a;
}
}
return a['Files'];
}, this.getJSON());
} catch (_) {
return false;
}
}
getJSON(): x[][] {
return [...this.Memory.values()].reduce((a, b) => {
a[b.Name] = b.getJSON();
return a;
}, {});
}
}
Result: (Thanks Michael M. and chill 389cc for helping me understand the error)
has(
query: string,
overwrite = null
) {
// If overwrite argument is not null, we are going use it.
let files = overwrite == null ? this.getJSON() : overwrite;
// Split string for getting more usable type with converting string to Array.
const QueryParams = query.split('->').filter(String);
// If we dont have no query, we can return current status.
if (QueryParams.length == 0) return overwrite;
if (Array.isArray(files)) {
const SearchFor = QueryParams.shift();
const Result = files.filter((e) => {
if (e instanceof Directory) {
const x = e.Name == SearchFor;
return x ? e : false;
}
return e.Name == SearchFor;
})[0];
// If we cant find any indexing result
if (!Result) return false;
// We found a file and if we dont have any query this is mean we found it!
if (Result instanceof File) return QueryParams.length == 0;
// We found a Directory and we doesnt have any Query now, so we can return true.
if (Result instanceof Directory && QueryParams.length == 0) return true;
if (
Result.Name != SearchFor ||
(QueryParams.length != 0 && Result.Files.length == 0)
)
// If name not suits or still we has Query and not enough file for indexing.
return false;
// If nothing happens on upper section, return rescyned version of this function.
return this.has(QueryParams.join('->'), Result.Files);
} else {
// If value is Object, Try Search param in object, and return it.
const Result = files[QueryParams.shift()];
return !Result ? false : this.has(QueryParams.join('->'), Result);
}
}
I can't replicate all of your code, but does this help?
interface Entry {
Name: string,
Type: string,
Value: Array<Entry> | any,
};
const Files = [
{
Name: "System",
Type: "directory",
Value: [
{
Name: "Main",
Type: "directory",
Value: [
{
Name: "Drivers",
Type: "directory",
Value: [
{
Name: "Startup",
Type: "file",
Value: "test", // change this to anything
},
],
},
],
},
],
},
];
function getEl(files: Array<Entry>, path: String) {
let path_walk = path.split("->");
let obj = files;
for (let part of path_walk) {
let found = false;
for (let entry of obj) {
if (entry.Name == part) {
obj = entry.Value;
found = true;
}
}
if (!found) return undefined;
}
return obj;
}
console.log(getEl(Files, "System->Main->Drivers")); // => [ { Name: 'Startup', Type: 'file', Value: 'test' } ]
console.log(getEl(Files, "System->Main->Drivers->Startup")); // => "test"
console.log(getEl(Files, "System->Main->Drivers->AnyWhere")); // => undefined
console.log(getEl(Files, "System->Main->AnyRandomDirectory")); // => undefined
There are some obvious problems, such as the fact that your example shows .has() being called with two arguments but it is defined in the class to only take in one. That being said, here is a function that, given a string query as you have and an array of objects like you have, would read the query and return if the array works for that query.
function has(fileSystem, query) {
const arrayOfArgs = query.split('->')
if (Array.isArray(fileSystem)) {
for (let i = 0; i < fileSystem.length; i++) {
if (fileSystem[i]['Name'] === arrayOfArgs[0]) {
if (arrayOfArgs.length === 1) {
// element found
return true; // replace this to return an actual value if that is desired.
}
if (fileSystem[i]['Type'] === 'directory') {
// if not, recurse in if it is a directory
return has(fileSystem[i]['Value'], arrayOfArgs.slice(1).join('->'));
} else {
// if it isn't a directory, don't try to recurse in
return false;
}
}
}
}
return false;
}
console.log(has(Files, 'System->Main->Drivers')); // true
console.log(has(Files, 'System->Main->Drivers->Startup')); // true
console.log(has(Files, 'System->Main->Drivers->AnyWhere')); // false
console.log(has(Files, 'System->Main->AnyRandomDirectory')); // false
You'll have to add your own types to get it back to TypeScript and obviously I pulled it out of the class for easier testing but it should be pretty easy to re-implement.

Create Javascript localStorage for website background change

Hello and big thanks for a all S.O community
I come today because i try to create local storage with Javascript for my users can change background and page settings on my website and find it back when page reload.
I tried many attempt but i'm so beginner for do make it work
var m = new s.a.Store({
modules: {
programs: p,
preferences: {
state: {
background: "images/backgrounds/background2.jpg",
preferredColor: "#1e90ff",
isWiFiConnected: !1
},
getters: {
background: function(t) {
return t.background
},
preferredColor: function(t) {
return t.preferredColor
},
isWiFiConnected: function(t) {
return t.isWiFiConnected
}
},
actions: {},
mutations: {
changePreferredColor: function(t, e) {
t.preferredColor = e
},
changeBackground: function(t, e) {
t.background = e
},
toggleWiFiConnection: function(t) {
t.isWiFiConnected = !t.isWiFiConnected
}
}
},
filesystem: d
},
strict: !1
});
i.a.prototype.$t = function(t) {
return t
}, i.a.config.devtools = !0, new i.a({
el: "#app",
store: m,
components: {
App: a.a
}
})
},
function(t, e, n) {
"use strict";
(function(e, n) {
var r = Object.freeze({});
function i(t) {
return null == t
}
function o(t) {
return null != t
}
function a(t) {
return !0 === t
}
function s(t) {
return "string" == typeof t || "number" == typeof t || "symbol" == typeof t || "boolean" == typeof t
}
function u(t) {
return null !== t && "object" == typeof t
}
there is the code i tried to add just before without sucess (blank page) :
var m = { ...localStorage };
localStorage.getItem("background");
localStorage.setItem("background");
Thanks for your support
Best regards

how to add custom speech in botframe work

I am working on Custom speech in bot framework.I add Bing simple speech it is working on my website: here is link :https://envolvebot.azurewebsites.net/
but now i want to know how can we add custom speech (LUIS custom speech) in our webchat bot?
I create custom speech using : https://westus.cris.ai/Home/CustomSpeech
Now i want to add it and want it to work like bing speech .
i am using following code.
/*! modernizr 3.6.0 (Custom Build) | MIT *
* https://modernizr.com/download/?-getusermedia-speechsynthesis !*/
!function (e, n, s) { function i(e, n) { return typeof e === n } function o() { var e, n, s, o, a, f, d; for (var c in t) if (t.hasOwnProperty(c)) { if (e = [], n = t[c], n.name && (e.push(n.name.toLowerCase()), n.options && n.options.aliases && n.options.aliases.length)) for (s = 0; s < n.options.aliases.length; s++)e.push(n.options.aliases[s].toLowerCase()); for (o = i(n.fn, "function") ? n.fn() : n.fn, a = 0; a < e.length; a++)f = e[a], d = f.split("."), 1 === d.length ? Modernizr[d[0]] = o : (!Modernizr[d[0]] || Modernizr[d[0]] instanceof Boolean || (Modernizr[d[0]] = new Boolean(Modernizr[d[0]])), Modernizr[d[0]][d[1]] = o), r.push((o ? "" : "no-") + d.join("-")) } } var t = [], a = { _version: "3.6.0", _config: { classPrefix: "", enableClasses: !0, enableJSClass: !0, usePrefixes: !0 }, _q: [], on: function (e, n) { var s = this; setTimeout(function () { n(s[e]) }, 0) }, addTest: function (e, n, s) { t.push({ name: e, fn: n, options: s }) }, addAsyncTest: function (e) { t.push({ name: null, fn: e }) } }, Modernizr = function () { }; Modernizr.prototype = a, Modernizr = new Modernizr, Modernizr.addTest("speechsynthesis", "SpeechSynthesisUtterance" in e), Modernizr.addTest("getUserMedia", "mediaDevices" in navigator && "getUserMedia" in navigator.mediaDevices); var r = []; o(), delete a.addTest, delete a.addAsyncTest; for (var f = 0; f < Modernizr._q.length; f++)Modernizr._q[f](); e.Modernizr = Modernizr }(window, document);
// Necessary for safari
// Safari will only speak after speaking from a button click
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
const params = BotChat.queryParams(location.search);
debugger;
function SpeakText() {
var msg = new SpeechSynthesisUtterance();
window.speechSynthesis.speak(msg);
document.getElementsByClassName("wc-mic")[0].removeEventListener("click", SpeakText);
}
if (isSafari) {
window.addEventListener("load", function () {
document.getElementsByClassName("wc-mic")[0].addEventListener("click", SpeakText);
});
}
var femaleVoice = null;
if (Modernizr.speechsynthesis) {
var baseSpeechPrototype = SpeechSynthesisUtterance.prototype;
SpeechSynthesisUtterance = function (msg) {
var utterance = new baseSpeechPrototype.constructor(msg);
if (femaleVoice != null)
utterance.voice = femaleVoice;
return utterance;
}
window.speechSynthesis.onvoiceschanged = function () {
var voice = "Microsoft Zira";
var safariVoice = "Samantha";
var voices = window.speechSynthesis.getVoices();
voices.forEach(function (v) {
if (v.name.startsWith(voice))
femaleVoice = v;
else if (v.name == safariVoice && v.lang == "en-US")
femaleVoice = v;
})
}
}
//// Needed to change between the two audio contexts
var AudioContext = window.AudioContext || window.webkitAudioContext;
//// Sets the old style getUserMedia to use the new style that is supported in more browsers even though the framework uses the new style
if (window.navigator.mediaDevices.getUserMedia && !window.navigator.getUserMedia) {
window.navigator.getUserMedia = function (constraints, successCallback, errorCallback) {
window.navigator.mediaDevices.getUserMedia(constraints)
.then(function (e) {
successCallback(e);
})
.catch(function (e) {
errorCallback(e);
});
};
}
const bot = {
id: params['botid'] || 'botid',
name: params['botname'] || 'botname'
};
window.botchatDebug = params['debug'] && params['debug'] === 'true';
var speechOptions;
if (Modernizr.speechsynthesis) {
speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({
fetchCallback: function (authFetchEventId) { return getBingToken() },
fetchOnExpiryCallback: function (authFetchEventId) { getBingToken() }
}),
speechSynthesizer: new BotChat.Speech.BrowserSpeechSynthesizer()
};
}
else if (Modernizr.getusermedia) {
speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({
fetchCallback: function (authFetchEventId) { return getBingToken() },
fetchOnExpiryCallback: function (authFetchEventId) { getBingToken() }
}),
speechSynthesizer: null
};
}
else {
speechOptions = null;
}
// for bot
var botConnection = new BotChat.DirectLine({
domain: params['domain'],
//token: document.getElementById("directLineToken").value,
secret: 'Secret',
webSocket: params['webSocket'] && params['webSocket'] === 'true' // defaults to true
});
BotChat.App({
sendTyping: true,
locale: params['locale'],
resize: 'detect',
speechOptions: speechOptions,
user: { id:'ID' name: "You" },
bot: { id: 'Vera', name: "Vera" },
botConnection: botConnection
}, document.getElementById('BotChatElement'));
function getBingToken() {
// Normally this token fetch is done from your secured backend to avoid exposing the API key and this call
// would be to your backend, or to retrieve a token that was served as part of the original page.
return fetch(
'https://api.cognitive.microsoft.com/sts/v1.0/issueToken',
{
headers: {
'Ocp-Apim-Subscription-Key': 'Key'
},
method: 'POST'
}
//).then(res => res.text());
).then(function (res) { return res.text() });
}
aNY BODY Know how to do this ?
Thank in advance .

WebComponents - Attribute Changed

From the link qr-code.js I have the code below.
Then I don't understand, on the highlighted line (60), what means the suffix: "Changed"?
attributeChangedCallback: {
value: function (attrName, oldVal, newVal) {
var fn = this[attrName+'Changed'];
if (fn && typeof fn === 'function') {
fn.call(this, oldVal, newVal);
}
this.generate();
}
Also I don't understand the usage of:
this[attrName+'Changed']
Could you explain me this?, I don't find any clear explanation about this on Google. Thanks.
Below is the full code:
'use strict';
(function(definition) {
if (typeof define === 'function' && define.amd) {
define(['QRCode'], definition);
} else if (typeof module === 'object' && module.exports) {
var QRCode = require('qrjs');
module.exports = definition(QRCode);
} else {
definition(window.QRCode);
}
})(function(QRCode) {
//
// Prototype
//
var proto = Object.create(HTMLElement.prototype, {
//
// Attributes
//
attrs: {
value: {
data: null,
format: 'png',
modulesize: 5,
margin: 4
}
},
defineAttributes: {
value: function () {
var attrs = Object.keys(this.attrs),
attr;
for (var i=0; i<attrs.length; i++) {
attr = attrs[i];
(function (attr) {
Object.defineProperty(this, attr, {
get: function () {
var value = this.getAttribute(attr);
return value === null ? this.attrs[attr] : value;
},
set: function (value) {
this.setAttribute(attr, value);
}
});
}.bind(this))(attr);
}
}
},
//
// LifeCycle Callbacks
//
createdCallback: {
value: function () {
this.createShadowRoot();
this.defineAttributes();
this.generate();
}
},
attributeChangedCallback: {
value: function (attrName, oldVal, newVal) {
var fn = this[attrName+'Changed'];
if (fn && typeof fn === 'function') {
fn.call(this, oldVal, newVal);
}
this.generate();
}
},
//
// Methods
//
getOptions: {
value: function () {
var modulesize = this.modulesize,
margin = this.margin;
return {
modulesize: modulesize !== null ? parseInt(modulesize) : modulesize,
margin: margin !== null ? parseInt(margin) : margin
};
}
},
generate: {
value: function () {
if (this.data !== null) {
if (this.format === 'png') {
this.generatePNG();
}
else if (this.format === 'html') {
this.generateHTML();
}
else if (this.format === 'svg') {
this.generateSVG();
}
else {
this.shadowRoot.innerHTML = '<div>qr-code: '+ this.format +' not supported!</div>'
}
}
else {
this.shadowRoot.innerHTML = '<div>qr-code: no data!</div>'
}
}
},
generatePNG: {
value: function () {
try {
var img = document.createElement('img');
img.src = QRCode.generatePNG(this.data, this.getOptions());
this.clear();
this.shadowRoot.appendChild(img);
}
catch (e) {
this.shadowRoot.innerHTML = '<div>qr-code: no canvas support!</div>'
}
}
},
generateHTML: {
value: function () {
var div = QRCode.generateHTML(this.data, this.getOptions());
this.clear();
this.shadowRoot.appendChild(div);
}
},
generateSVG: {
value: function () {
var div = QRCode.generateSVG(this.data, this.getOptions());
this.clear();
this.shadowRoot.appendChild(div);
}
},
clear: {
value: function () {
while (this.shadowRoot.lastChild) {
this.shadowRoot.removeChild(this.shadowRoot.lastChild);
}
}
}
});
//
// Register
//
document.registerElement('qr-code', {
prototype: proto
});
});
As #Jhecht suggested, it's a combination of the name of a attribute and the suffix "Changed" in order to create generic method names.
For example if the <qr-code> element has an attribute "foo" that is added, updated or removed, then the callback will define the fn variable to this["fooChanged"], which is equivalent to this.fooChanged.
If this method exists, it will be invoked by fn.call().
However I see nowhere in the code you posted such method signature attached to the custom element prototype, so it's useless code until further notice.

Set empty object while setting property on nested object and return the empty object

I have json object which i need to set/override some properties.
This part is done (i too the solution from this answer)
My problem now is handle the case the path to change is not given (or empty.)In this case it shoudl just return an empty Obj which i could then handle and return an error message.
var obj = { "users": {
"profile": {
"name": "markus",
"age": 28
}
}
}
var changes = [
{
path: ['users', 'profile', 'name'],
changes: "Nino"
},
{
path: [],
changes: "fail"
}
];
// Func to set new values
function set(jsonObj, path, value, updatedJson) {
if(path.length === 0 || value.length === 0) {
updatedJson = {};
return updatedJson;
}
if(path.length === 1){
updatedJson[path] = value;
} else {
for(var i = 0; i < path.length-1; i++) {
var elem = path[i];
if( !updatedJson[elem] ) {
updatedJson[elem] = {}
}
updatedJson = updatedJson[elem];
}
updatedJson[path[path.length-1]] = value;
}
return updatedJson;
}
var updatedJson = Object.assign(obj);
changes.forEach( function(changeObj){
var path = changeObj.path;
set(obj, path, changeObj.changes, updatedJson);
});
// handle empty object case
if(Object.keys(updatedJson).length === 0 && obj.constructor === Object){
callback({
success: false,
message: 'File not updated. One or more property are incorrect.'
})
} else {
callback({
success: updatedJson,
message: 'File was succefully updated'
})
}
Changes[0] pass and set new value to the obj.
Changes[1] should instead set updatedJson to empty one, which it does but when i check if Object is empty, updatedJson is full again.
Can someone explain me why is this happening?
And how can i handle error like empty path to object's value?
Try this:
var obj = { "users": {
"profile": {
"name": "markus",
"age": 28
}
}
}
var changes = [
{
path: ['users', 'profile', 'name'],
changes: "Nino"
},
{
path: [],
changes: "fail"
}
];
// Func to set new values
function set(jsonObj, path, value, updatedJson) {
if(path.length === 0 || value.length === 0) {
updatedJson = {};
return updatedJson;
}
if(path.length === 1){
updatedJson[path] = value;
} else {
for(var i = 0; i < path.length-1; i++) {
var elem = path[i];
if( !updatedJson[elem] ) {
updatedJson[elem] = {}
}
updatedJson = updatedJson[elem];
}
updatedJson[path[path.length-1]] = value;
}
return updatedJson;
}
var success = true;
var updatedJson = Object.assign(obj);
changes.forEach( function(changeObj){
var path = changeObj.path;
var result = set(obj, path, changeObj.changes, updatedJson);
if(Object.keys(result).length === 0 && result.constructor === Object)
success = false;
});
// handle empty object case
if(!success){
callback({
success: false,
message: 'File not updated. One or more property are incorrect.'
})
} else {
callback({
success: updatedJson,
message: 'File was succefully updated'
})
}

Categories

Resources