
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
A tiny, sensible, client-side MVC framework in modern Javascript. It was created to provide a rich but minimal set of tools for creating scalable and powerful Javascript in the real world of shipping code quickly and correctly.
npm install dotmvc
All of the components are accessible as members of the module:
var View = require('dotmvc').View;
var Controller = require('dotmvc').Controller;
...
triggerPropertyChange()
method.You can either directly instantiate an object from the Observable
class, or
mixin the methods from Observable.prototype
, or subclass it via prototypical
inheritance. All three methods will give you the functionality needed to
trigger event changes or create observable properties.
Creating an observable property that is a function will track any dependent observable properties accessed during function evaluation.
__mixin(Person, Observable);
function Person()
{
Person.observable({
firstName : 'John',
lastName : 'Doe',
fullName : function() {
return this.firstName + ' ' + this.lastName;
}
});
}
var person = new Person();
person.onPropertyChange({
firstName: function() { console.log('firstName changed'); },
fullName: function() { console.log('fullName changed'); }
});
person.firstName = 'Bob';
This creates a Person
object called person
, and wires up some functions to
be fired whenever the firstName
or fullName
properties change. The console
output would be:
firstName changed.
fullName changed.
as fullName
is a computed observable property with firstName
as a dependent
property.
Observable
objects as the
source, allowing property changes in the source to propigate to the target.View
in Dot MVC is a super-powered chunk of UI. All display logic and
visual code lives inside of a view.render()
method. This method is responsible for
updating the DOM to reflect the state of the view and its bound data. The
default behavior depends on whether the view has a template or layout
set.context
property that corresponds to the data that
is currently bound to that view. If the context
is observable and emits
change events, the view will automatically be re-rendered.To access a view's root DOM node, use its element
property, or the cached
jQuery object $element
. Don't use global jQuery selectors to find elements
within the view, use the proxied find
function with the $
method on the
view:
var index = this.$('li.selected').data('index');
Event delegation is powered by jQuery's on()
method. This allows you to
specify a callback on the root, immutable view DOM node that will catch any
events bubbling up from within. All callbacks are automatically bound to the
view's this
pointer.
this.delegate('li', 'click', this.onItemClick);
This means even if the DOM identites of the internal elements change (or are
added after the delegate
method is called), events will still be caught as
expected.
A view should not contain any business or domain logic, but rather delegate any interaction to either its own data context or a higher-level object, via a command. Commands bubble up the DOM hierarchy until finding a view whose own data context can handle the command.
this.executeCommand({ saveUserPreferences: user });
With a shortcut for delegating DOM events to fire off commands:
this.delegateCommand('#save-button', 'click', { saveUserPreferences: user });
A view can either have a template, or a layout, or neither... in which case all render logic must be done by hand.
Both templates and layouts are functions that generate HTML when passed a reference to the view. Underscore, Handlebars, etc. can compile functions like this.
A template will be injected into a view on every render. This means the entire
previous HTML content of a view is lost, along with any DOM nodes, their
events, and data (events bound with delegate
are bound to the view's DOM
root-- which doesn't change). This is best for simple views whose content
represents a single object.
A layout will only be injected into a view once, guaranteeing the identity of the layout DOM elements does not change. This is best when designing larger views that a composed of several smaller subviews.
Both layouts and templates can be set with their corresponding instance methods or on the View's constructor as a "static property", e.g.,
WidgetView.TEMPLATE = htmlTemplatingFunction;
// Only works if the view has been initialized yet
myView.setTemplate(htmlTemplatingFunction);
Compositing views can be done by using the createViews()
method to
instantiate a new View on an existing interior DOM node. Calling this method
while using a template will log a warning, as the identity of interior DOM
could potentially change, losing the sub view (see Layouts vs Templates above).
this.createViews({
'.view-widget-detail': {
View: WidgetDetail,
context: new Binding(this, 'context.currentGroup.currentWidget')
},
'.view-group-detail': {
View: WidgetGroup,
context: new Binding(this, 'context.currentGroup')
}
});
The hash is a mapping between a jQuery selector and information on how to
create the subview. The View
parameter specifies the view class, and the
context
parameter can either be a Binding
or just an object.
$ npm test
MIT
FAQs
A tiny, sensible, client-side MVC framework in modern Javascript.
We found that dotmvc demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.