codemirror inner mode auto indentation problems - codemirror

I'm having some trouble getting codemirror to apply the correct autoindentation to inner modes in a mixed mode.
You can see a live version of the mode (and how it's not working) here:
https://extremely-alpha.iodide.io/notebooks/216/ but in short the idea is to be able to use matlab style block delimiters to switch between languages like this:
%% js
[1,2,3].forEach(i => {
console.log(i)
})
%% py
for i in range(5):
for j in range(10):
print i+j
%% css
div#foo {
border: 1px solid pink
}
As you can see from my example link, the syntax highlighting works ok, but you'll also notice that the indentation is not working as desired.
The code for this codemirror mode is here on github. It is very much based on codemirror's html mixed mode.
I tried adding copyState to my code, again following the html mixed mode --
copyState: state => {
let local;
if (state.localState) {
console.log("state.localState copied");
local = CodeMirror.copyState(state.localMode, state.localState);
}
return {
token: state.token,
localMode: state.localMode,
localState: local
};
},
-- but this results in a different kind of weird indentation behavior, and doesn't end up working.
I've been banging my head against this for quite some time, and I haven't been able to piece it together via google, api docs and forums, so any help would be greatly appreciated! Thank you!

in case anyone comes across this problem in the future: it turns out codemirror modes do not typically come with sensible defaults built in, or at least they are not loaded by default when you use CodeMirror.getMode(...). In my case, I had to change from
const innerModes = {
js: CodeMirror.getMode({}, { name: "javascript" }),
py: CodeMirror.getMode({}, { name: "python" }),
md: CodeMirror.getMode({}, { name: "markdown" }),
css: CodeMirror.getMode({}, { name: "css" }),
raw: CodeMirror.getMode({}, { name: "text/plain" }),
fetch: CodeMirror.getMode({}, { name: "fetch" })
};
to:
const innerModes = {
js: CodeMirror.getMode(
{ indentUnit: 2, statementIndent: 2 },
{ name: "javascript" }
),
py: CodeMirror.getMode(
{ indentUnit: 4, hangingIndent: 4 },
{ name: "python" }
),
md: CodeMirror.getMode({}, { name: "markdown" }),
css: CodeMirror.getMode({ indentUnit: 2 }, { name: "css" }),
raw: CodeMirror.getMode({}, { name: "text/plain" }),
fetch: CodeMirror.getMode({}, { name: "fetch" })
};
This prevented NaNs from getting passed out of the indent function of the sub-modes.

Related

how to write fixer for custom eslint rule

I am writing custom eslint rules. The rules are flagging the correct spot in the code, but Visual Studio Code is not offering my quick fixes.
Here's the start of the code:
module.exports = {
meta: {
type: "suggestion",
docs: {
description: "Use design tokens",
category: "Design System",
recommended: false
},
fixable: "code"
},
And Here is, where I report the problem:
for (const m of matchedTokens) {
suggest.push({
desc: property.value.raw + " should be " + m,
fix(fixer) {
return fixer.replaceText(property.value, m);
}
})
}
context.report({
node: property,
message: 'Possible value for replacement of {{ key }} with design token',
data: {
key: property.key.name
},
suggest
})
How can I make suggestions work in the IDE? Is my expectation correct that these should show as quick fix in Visual Studio code? Is there anything else I need to do to opt into fixes?

Nuxt.js - Implementing a component using Plugin

I would like to implement a custom Toaster component into my NuxtJs application by this method this.$toast.show({}) What is the best way of approaching this? Sadly I can't find any documentation on this.
Sorry, I arrive one year late...
I had the same proplem. Here is my code:
The index of my plugin (index.js ; Nofification.vue is a classical Vue component):
import Notifications from './Notifications.vue'
const NotificationStore = {
state: [], // here the notifications will be added
settings: {
overlap: false,
horizontalAlign: 'center',
type: 'info',
timeout: 5000,
...
},
setOptions(options) {
this.settings = Object.assign(this.settings, options)
},
removeNotification(timestamp) {
...
},
addNotification(notification) {
...
},
notify(notification) {
...
},
}
const NotificationsPlugin = {
install(Vue, options) {
const app = new Vue({
data: {
notificationStore: NotificationStore,
},
methods: {
notify(notification) {
this.notificationStore.notify(notification)
},
},
})
Vue.prototype.$notify = app.notify
Vue.notify = app.notify
Vue.prototype.$notifications = app.notificationStore
Vue.component('Notifications', Notifications)
if (options) {
NotificationStore.setOptions(options)
}
},
}
export default NotificationsPlugin
Here I call my plugin and inject it in Nuxt:
import Notifications from '~/components/NotificationPlugin'
Vue.use(Notifications)
export default (context, inject) => {
inject('notify', Vue.notify)
}
In my case, I use it in another plugin (nuxtjs axios).
import NOTIFICATIONS from '~/constants/notifications'
export default function ({ error, $axios, app }) {
// Using few axios helpers (https://axios.nuxtjs.org/helpers):
$axios.onError((axiosError) => {
// eslint-disable-next-line no-console
console.log('Axios: An error occured! ', axiosError, axiosError.response)
if (process.server) {
...
} else {
app.$notify({
message: 'Mon message',
timeout: NOTIFICATIONS.DEFAULT_TIMEOUT,
icon: 'tim-icons icon-spaceship',
horizontalAlign: NOTIFICATIONS.DEFAULT_ALIGN_HORIZONTAL,
verticalAlign: NOTIFICATIONS.DEFAULT_ALIGN_VERTICAL,
type: 'success',
})
console.log('PRINT ERROR')
return Promise.resolve(true)
}
})
}
As I injected it, I think I could have done export default function ({ error, $axios, app, $notify }) { and directly use $notify (and not the app.$notify).
If you want a better understanding, feel free to consult #nuxtjs/toast which works the same way:
https://github.com/nuxt-community/community-modules/blob/master/packages/toast/plugin.js
And the matching Vue component:
https://github.com/shakee93/vue-toasted/blob/master/src/index.js
Good luck, this is not easy stuff. I'll try to add something easier to understand in the docs!
you can find in this package https://www.npmjs.com/package/vue-toasted
installation
npm install vue-toasted --save
make a file as name toast.js in plugin folder
toast.js
import Vue from 'vue';
import Toasted from 'vue-toasted';
Vue.use(Toasted)
add this plugin to nuxt.config.js
plugins: [
{ src: '~/plugins/toast', ssr: false },
],
now you able to use in your methods like this
this.$toasted.show('hello i am your toast')
hope this helps

Getting an ' instance.requestPaymentMethod is not a function' in Braintree's sample

I'm getting an instance.requestpaymentmethod is not a function when I was just following along the tutorial for custom-field integration found here:
https://developers.braintreepayments.com/start/tutorial-hosted-fields-node
The error happens when I click on the "Pay" button.
Did anyone solve this problem? My assumption is that the code isn't updated or the script sources changed somewhat. If anyone from Braintree can actually help, that'll be great.
Thanks!
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
I took a look at the example code snippet in the guide you shared and I was able to find the culprit. First off, the error you're getting is expected as the requestPaymentMethod method actually belongs to our Drop-In UI solution and the Hosted Fields JS library doesn't have such module. I informed our Documentation team to get that code example updated.
That being said, you can find a working example in our Hosted Fields guide. If you check the function (hostedFieldsErr, hostedFieldsInstance) callback function, you'll see that the payment nonce is created by the tokenize function of the hostedFieldsInstance.
I also ran into this issue today. Use the following code in <script> tag. It will work for you.
var form = document.querySelector('#hosted-fields-form');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '<YOUR_TOKENIZATION_KEY>'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
console.log('Got a nonce: ' + payload.nonce);
$.ajax({
type: 'POST',
url: '<YOUR_API_URL>',
data: { 'paymentMethodNonce': payload.nonce }
}).done(function (result) {
hostedFieldsInstance.teardown(function (teardownErr) {
if (teardownErr) {
console.error('Could not tear down Drop-in UI!');
} else {
console.info('Drop-in UI has been torn down!');
$('#submit-button').remove();
}
});
if (result.success) {
$('#checkout-message').html('<h1>Success</h1><p>Your Drop-in UI is working! Check your sandbox Control Panel for your test transactions.</p><p>Refresh to try another transaction.</p>');
} else {
console.log(result);
$('#checkout-message').html('<h1>Error</h1><p>Check your console.</p>');
}
});
});
}, false);
});
});

Searching for ObjectID after implementing routing in Algolia

I have feature whereby am constructing a url like :
http://localhost/listings?q=&idx=content_index&p=0&dFR[objectID][0]=97&dFR[objectID][1]=96
It creates a facetFilters: [["objectID:97","objectID:96"]]"}. I have a clear All feature also which clear all the filters:
search.addWidget(
instantsearch.widgets.clearAll({
container: '#clearAll',
templates: {
link: '<i class="icon icon-undo2"></i>'
},
autoHideContainer: false,
clearsQuery: true
})
);
This works perfectly fine and clears the above filter also. But the issue came when started routing. With routing,
http://localhost/listings?q=&idx=content_index&p=0&dFR%5Bgenres.name%5D%5B0%5D=Comedy
changed to :
http://localhost/listings?genres=Comedy
Have done the below changes for the above:
routing: {
stateMapping: {
stateToRoute(uiState) {
return {
query: uiState.query,
// we use the character ~ as it is one that is rarely present in data and renders well in urls
genres:
uiState.refinementList &&
uiState.refinementList['genres.name'] &&
uiState.refinementList['genres.name'].join('~'),
page: uiState.page
};
},
routeToState(routeState) {
return {
query: routeState.query,
refinementList: {
'genres.name': routeState.genres && routeState.genres.split('~'),
},
page: routeState.page
};
}
}
},
Have to implement the same functionality for objectID. How to do that?

Coffescript not compiling valid source

I'm calling this function and get error in this place: data: { key: node.parent.data.key } saing "Unexpected {". Is there something wrong. because I can't find the error.
$("#discipline-list", #el).dynatree({
fx: { height: "toggle",
duration: 100 },
initAjax: {
url: "/disciplines",
data: { mode: "funnyMode" }
},
onLazyRead: (node) ->
console.log(node);
node.appendAjax({url: "/disciplines_details",
data: { key: node.parent.data.key }
});
});
Coffee script is not appreciating having the anonymous object properties on the same line. Adding a single newline fixes this...
$("#discipline-list", #el).dynatree({
fx: { height: "toggle",
duration: 100 },
initAjax: {
url: "/disciplines",
data: { mode: "funnyMode" }
},
onLazyRead: (node) ->
console.log(node);
node.appendAjax({
url: "/disciplines_details",
data: { key: node.parent.data.key }
});
});
EDIT: How to convert js to coffee script...
go to http://js2coffee.org/ and paste the js (corrected from your version)
$("#discipline-list", this.el).dynatree({
fx: { height: "toggle",
duration: 100 },
initAjax: {
url: "/disciplines",
data: { mode: "funnyMode" }
},
onLazyRead: function(node){
console.log(node);
node.appendAjax({ url: "/disciplines_details",
data: { key: node.parent.data.key }
});
}
});
You will end up with well formed coffee script...
$("#discipline-list", #el).dynatree
fx:
height: "toggle"
duration: 100
initAjax:
url: "/disciplines"
data:
mode: "funnyMode"
onLazyRead: (node) ->
console.log node
node.appendAjax
url: "/disciplines_details"
data:
key: node.parent.data.key
I don't know exactly what is wrong, but the more canonical way to write it would be
node.appendAjax
url: "/disciplines_details"
data:
key: node.parent.data.key
With compile errors like that, always first go to Try Coffeescript and see how it gets parsed. That makes it very easy and quick to fix in most cases.
The object properties on the same line are confusing the parser:
node.appendAjax({url: "/disciplines_details",
Just move url to the next line and it should work:
node.appendAjax({
url: "/disciplines_details",
That said, you're still writing javascript.
Whitespace is significant in coffeescript (i.e. you can't minify it). Correct indentation is essential, and this code is all wrong. Fix indentation, get rid of commas and semi-colons:
$("#discipline-list", #el).dynatree({
fx: {
height: "toggle"
duration: 100
}
initAjax: {
url: "/disciplines",
data: { mode: "funnyMode" }
}
onLazyRead: (node) ->
console.log(node)
node.appendAjax({
url: "/disciplines_details"
data: { key: node.parent.data.key }
})
})
Then proceed to get rid of brackets and parenthesis as in #Billy's last sample. If you're not comfortable you should try sticking to plain javascript for some time.