/// <summary> /// JavaScript callback. Returns absolute path to the file that is referenced from the file in the /// editor. Implementation copied from the Emmet project source code. /// </summary> public InternalHandle LocateFile( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 2) { this.TraceError("IEmmetFile locateFile called with invalid number of arguments."); return engine.CreateValue(false); } string editorFile = args[0].AsString; string targetFile = args[1].AsString; if (targetFile.StartsWith("HTTP", System.StringComparison.InvariantCultureIgnoreCase)) return engine.CreateValue(targetFile); string folder = Path.GetDirectoryName(editorFile); do { string retVal = Path.Combine(folder, targetFile); if (File.Exists(retVal)) return engine.CreateValue(retVal); } while (folder.Length > 3); return engine.CreateValue(string.Empty); }
/// <summary> /// JavaScript callback. Returns character indexes of selected text: object with <code>start</code> /// and <code>end</code> properties.If there's no selection, should return object with /// <code>start</code> and <code>end</code> properties referring to current caret position. /// </summary> public InternalHandle GetSelectionRange( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { var selection = _editor.GetSelectionRange(); ObjectHandle retVal = engine.CreateObject(); retVal.SetProperty("start", engine.CreateValue(selection.Start)); retVal.SetProperty("end", engine.CreateValue(selection.End)); return retVal; }
/// <summary> /// JavaScript callback. Creates selection from <code>start</code> to <code>end</code> character /// indexes. If <code>end</code> is omitted, this method should place caret and <code>start</code> /// index. /// </summary> public InternalHandle CreateSelection( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { if (args.Length == 2) { int start = args[0].AsInt32; int end = args[0].AsInt32; _editor.CreateSelection(start, end); } else { return SetCarretPos(engine, isConstructCall, self, args); } return engine.CreateValue(true); }
/// <summary> /// JavaScript callback. Creates selection from <code>start</code> to <code>end</code> character /// indexes. If <code>end</code> is omitted, this method should place caret and <code>start</code> /// index. /// </summary> public InternalHandle CreateSelection( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { if (args.Length == 2) { int start = args[0].AsInt32; int end = args[0].AsInt32; _editor.CreateSelection(start, end); } else { return(SetCarretPos(engine, isConstructCall, self, args)); } return(engine.CreateValue(true)); }
/// <summary> /// JavaScript callback. Saves the specified content to the file with the specified name. /// </summary> public InternalHandle Save( V8Engine engine, bool isConstructorCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 2) { this.TraceError("IEmmetFile save called with invalid number of arguments."); return(engine.CreateValue(false)); } string filePath = args[0].AsString; string content = args[1].AsString; File.WriteAllText(filePath, content); return(engine.CreateValue(true)); }
protected HandleProxy *_IndexedPropertySetter(Int32 index, HandleProxy *value, ref ManagedAccessorInfo info) { try { using (InternalHandle hValue = new InternalHandle(value, false)) { var obj = _Engine._GetObjectWeakReference(info.ManagedObjectID); if (obj == null) { return(null); } var mo = obj.Reset() as IV8ManagedObject; return(mo != null?mo.IndexedPropertySetter(index, hValue) : null); } } catch (Exception ex) { return(_Engine.CreateError(Exceptions.GetFullErrorMessage(ex), JSValueType.ExecutionError)); } }
public InternalHandle TestJSFunction1(V8Engine engine, bool isConstructCall, InternalHandle _this, params InternalHandle[] args) { // ... there can be two different returns based on the call mode! ... // (tip: if a new object is created and returned instead (such as V8ManagedObject or an object derived from it), then that object will be the new object (instead of "_this")) if (isConstructCall) { var obj = engine.GetObject(_this); obj.AsDynamic.x = args[0]; ((dynamic)obj).y = 0; // (native objects in this case will always be V8NativeObject dynamic objects) obj.SetProperty(0, engine.CreateValue(100)); obj.SetProperty("1", engine.CreateValue(100.2)); obj.SetProperty("2", engine.CreateValue("300")); obj.SetProperty(4, engine.CreateValue(new DateTime(2013, 1, 2, 3, 4, 5, DateTimeKind.Utc))); return(_this); } else { return(args.Length > 0 ? args[0] : InternalHandle.Empty); } }
public bool Load() { bool state = include(g_EntryFileName); if (state) { InternalHandle h = engine.GlobalObject.GetProperty("PluginInfo"); if (!h.IsObject) { Logger.LogError(g_EntryFileName + " has no 'PluginInfo' defined."); return(false); } pluginInfo = new PluginInfo(); pluginInfo.Name = h.GetProperty("Name").AsString; pluginInfo.Version = h.GetProperty("Version").AsString; pluginInfo.Author = h.GetProperty("Author").AsString; pluginInfo.Description = h.GetProperty("Description").AsString; } return(state); }
protected HandleProxy *_IndexedPropertySetter(Int32 index, HandleProxy *value, ref ManagedAccessorInfo info) { try { InternalHandle hValue = value; var obj = _Engine._GetExistingObject(info.ManagedObjectID); if (obj == null) { return(null); } var mo = obj as IV8ManagedObject; var result = mo != null?mo.IndexedPropertySetter(index, hValue) : null; return(result); } catch (Exception ex) { return(_Engine.CreateError(Exceptions.GetFullErrorMessage(ex), JSValueType.ExecutionError)); } }
internal void OnKeyDown(int keyCode, int charCode) { if (v8.IsDisposed) { return; } using (Handle functHandle = v8.Execute("document.onkeydown", SOURCE_NAME, false)) { if (functHandle.ValueType != JSValueType.CompilerError && functHandle.IsFunction) { InternalHandle obj = v8.CreateObject(); obj.SetProperty("keyCode", keyCode); obj.SetProperty("charCode", charCode); functHandle.AsInternalHandle.StaticCall(obj); } } }
/// <summary> /// Calls the native V8 proxy library to create the value instance for use within the V8 JavaScript environment. /// <para>This overload provides a *quick way* to construct an array of strings. /// One big memory block is created to marshal the given strings at one time, which is many times faster than having to create an array of individual native strings.</para> /// </summary> public InternalHandle CreateValue(IEnumerable <string> items) { if (items == null) { return(V8NetProxy.CreateArray(_NativeV8EngineProxy, null, 0)); } var itemsEnum = items.GetEnumerator(); int strBufSize = 0; // (size needed for the string chars portion of the memory block) int itemsCount = 0; while (itemsEnum.MoveNext()) { // get length of all strings together strBufSize += itemsEnum.Current.Length + 1; // (+1 for null char) itemsCount++; } itemsEnum.Reset(); int strPtrBufSize = Marshal.SizeOf(typeof(IntPtr)) * itemsCount; // start buffer size with size needed for all string pointers. char **oneBigStringBlock = (char **)Utilities.AllocNativeMemory(strPtrBufSize + Marshal.SystemDefaultCharSize * strBufSize); char **ptrWritePtr = oneBigStringBlock; char * strWritePtr = (char *)(((byte *)oneBigStringBlock) + strPtrBufSize); int itemLength; while (itemsEnum.MoveNext()) { itemLength = itemsEnum.Current.Length; Marshal.Copy(itemsEnum.Current.ToCharArray(), 0, (IntPtr)strWritePtr, itemLength); Marshal.WriteInt16((IntPtr)(strWritePtr + itemLength), 0); Marshal.WriteIntPtr((IntPtr)ptrWritePtr++, (IntPtr)strWritePtr); strWritePtr += itemLength + 1; } InternalHandle handle = V8NetProxy.CreateStringArray(_NativeV8EngineProxy, oneBigStringBlock, itemsCount); Utilities.FreeNativeMemory((IntPtr)oneBigStringBlock); return(handle); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Same as "GetObject()", but used internally for getting objects that are associated with templates (such as getting function prototype objects). /// </summary> internal T _GetObject <T>(ITemplate template, InternalHandle handle, bool createIfNotFound = true, bool initializeOnCreate = true, bool connectNativeObject = true) where T : V8NativeObject, new() { T obj = null; try { if (handle.IsEmpty) { return(null); } if (handle.Engine != this) { throw new InvalidOperationException("The specified handle was not generated from this V8Engine instance."); } var weakRef = _GetObjectWeakReference(handle.ObjectID); // (if out of bounds or invalid, this will simply return null) if (weakRef != null) { obj = weakRef.Reset() as T; if (obj != null && !typeof(T).IsAssignableFrom(obj.GetType())) { throw new InvalidCastException("The existing object of type '" + obj.GetType().Name + "' cannot be converted to type '" + typeof(T).Name + "'."); } } if (obj == null && createIfNotFound) { handle.ObjectID = -1; // (managed object doesn't exist [perhaps GC'd], so reset the ID) obj = _CreateObject <T>(template, handle.PassOn(), initializeOnCreate, connectNativeObject); } } finally { handle._DisposeIfFirst(); } return(obj); }
/// <summary> /// JavaScript callback. Replace editor's content or it's part (from <code>start</code> to /// <code>end</code> index). If <code>value</code> contains <code>caret_placeholder</code>, the editor /// will put caret into this position. If you skip <code>start</code> and <code>end</code> arguments, /// the whole target's content will be replaced with <code>value</code>. /// If you pass <code>start</code> argument only, the <code>value</code> will be placed at /// <code>start</code> string index of current content. /// If you pass <code>start</code> and <code>end</code> arguments, the corresponding substring of /// current target's content will be replaced with <code>value</code>. /// </summary> public InternalHandle ReplaceContent( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { string rawContent = args[0].AsString; int regionStart = args.Length > 1 ? args[1].AsInt32 : -1; int regionLength = args.Length > 2 ? args[2].AsInt32 - regionStart : 0; bool indentContent = args.Length == 4 ? args[3].AsBoolean : true; this.Trace($"Received new content for the editor: {rawContent}"); // Extract tab stops placeholders from the specified content. var tabStops = TabStopsParser.ParseContent(engine, rawContent); _editor.ReplaceContentRange(tabStops.Content, regionStart, regionStart + regionLength); if (null != tabStops.TabStops) { Range[] tabStopRanges = tabStops.TabStops; // Tab stop offsets are relative to the newly generated content ranges, we need to convert // them to the document-wide offsets. if (regionStart > 0) { tabStopRanges = tabStopRanges.Select( item => new Range(item.Start + regionStart, item.End + regionStart)).ToArray(); } _editor.TrackTabStops(tabStopRanges, tabStops.TabStopGroups); } if (indentContent) { _editor.FormatRegion(regionStart, regionStart + tabStops.Content.Length); } return(engine.CreateValue(true)); }
/// <summary> /// JavaScript callback. Creates absolute path by concatenating two arguments. /// </summary> public InternalHandle CreatePath( V8Engine engine, bool isConstructorCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 2) { this.TraceError("IEmmetFile createPath called with invalid number of arguments."); return(engine.CreateValue(false)); } string parent = args[0].AsString; string fileName = args[1].AsString; if (Path.HasExtension(parent)) { parent = Path.GetDirectoryName(parent); } return(engine.CreateValue(Path.Combine(parent, fileName))); }
private InternalHandle XHRSend(V8Engine engine, bool isConstructCall, InternalHandle _this, InternalHandle[] args) { string data = null; try { if (_req.Method == "POST" && args.Length == 1) { if (args[0].IsString) { var pd = Encoding.UTF8.GetBytes(args[0].AsString); _req.GetRequestStream().Write(pd, 0, pd.Length); } else if (args[0].IsArray) { var pd = (byte[])Types.ChangeType(args[0].Value, typeof(char[])); _req.GetRequestStream().Write(pd, 0, pd.Length); } } _rsp = (HttpWebResponse)_req.GetResponse(); if (_rsp.StatusCode == HttpStatusCode.OK) { var d = new StreamReader(_rsp.GetResponseStream()).ReadToEnd(); if (!string.IsNullOrEmpty(d)) { data = d; } } } catch { } if (data != null) { return(Engine.CreateValue(data)); } return(null); }
/// <summary> /// JavaScript callback. Reads the specified file content and returns it as string. /// </summary> public InternalHandle Read( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 3) { this.TraceError("IEmmetFile read called with invalid number of arguments."); return(engine.CreateValue(false)); } string targetFilePath = args[0].AsString; int chunkSize = args[1].AsInt32; ObjectHandle callback = args[2]; if (!File.Exists(targetFilePath)) { this.TraceError($"Emmet requested file {targetFilePath} that does not exist."); callback.StaticCall(engine.CreateValue(true), engine.CreateNullValue()); return(engine.CreateValue(false)); } char[] buf = new char[chunkSize]; FileStream stream = File.OpenRead(targetFilePath); using (StreamReader reader = new StreamReader(stream)) { chunkSize = reader.ReadBlock(buf, 0, chunkSize); } string retVal = new string(buf, 0, chunkSize); callback.StaticCall(engine.CreateValue(false), engine.CreateValue(retVal)); return(engine.CreateValue(true)); }
public void CompileAndExecute(string script) { if (isDisposing) { return; } const string ES_REF = "ecmascript:"; const string JS_REF = "javascript:"; script = script.TrimStart(); string start = script.Substring(0, ES_REF.Length).ToLower(); script = start.StartsWith(ES_REF) ? script.Remove(0, ES_REF.Length) : script; script = start.StartsWith(JS_REF) ? script.Remove(0, JS_REF.Length) : script; using (InternalHandle handle = v8.Compile(script, SOURCE_NAME, false).AsInternalHandle) { if (!handle.IsError) { try { Handle result = v8.Execute(handle, true); //handle.Dispose(); } catch (Exception ex) { ConsoleColor tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("(SCRIPT) {0}", ex.Message); Console.ForegroundColor = tmp; } } } }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls the V8 'SetAccessor()' function on the underlying native 'v8::ObjectTenplate' instance to create a property that is controlled by "getter" and "setter" callbacks. /// <para>Note: This is template related, which means all objects created from this template will be affected by these special properties.</para> /// </summary> public void SetAccessor(string name, V8NativeObjectPropertyGetter getter, V8NativeObjectPropertySetter setter, V8PropertyAttributes attributes = V8PropertyAttributes.None, V8AccessControl access = V8AccessControl.Default) { if (name.IsNullOrWhiteSpace()) { throw new ArgumentNullException("name (cannot be null, empty, or only whitespace)"); } var engine = Engine; V8NetProxy.SetObjectTemplateAccessor(_NativeObjectTemplateProxy, -1, name, _Engine._StoreAccessor <ManagedAccessorGetter>(_NativeObjectTemplateProxy->ObjectID, "get_" + name, (HandleProxy * _this, string propertyName) => { try { using (InternalHandle hThis = _this) { return(getter != null ? getter(hThis, propertyName) : null); } } catch (Exception ex) { return(engine.CreateError(Exceptions.GetFullErrorMessage(ex), JSValueType.ExecutionError)); } }), _Engine._StoreAccessor <ManagedAccessorSetter>(_NativeObjectTemplateProxy->ObjectID, "set_" + name, (HandleProxy * _this, string propertyName, HandleProxy * value) => { try { using (InternalHandle hThis = _this) { return(setter != null ? setter(hThis, propertyName, value) : null); } } catch (Exception ex) { return(engine.CreateError(Exceptions.GetFullErrorMessage(ex), JSValueType.ExecutionError)); } }), access, attributes); }
/// <summary> /// JavaScript callback. Reads the specified file content and returns it as string. /// </summary> public InternalHandle Read( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 3) { this.TraceError("IEmmetFile read called with invalid number of arguments."); return engine.CreateValue(false); } string targetFilePath = args[0].AsString; int chunkSize = args[1].AsInt32; ObjectHandle callback = args[2]; if (!File.Exists(targetFilePath)) { this.TraceError($"Emmet requested file {targetFilePath} that does not exist."); callback.StaticCall(engine.CreateValue(true), engine.CreateNullValue()); return engine.CreateValue(false); } char[] buf = new char[chunkSize]; FileStream stream = File.OpenRead(targetFilePath); using (StreamReader reader = new StreamReader(stream)) { chunkSize = reader.ReadBlock(buf, 0, chunkSize); } string retVal = new string(buf, 0, chunkSize); callback.StaticCall(engine.CreateValue(false), engine.CreateValue(retVal)); return engine.CreateValue(true); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls an object property with a given name on a specified object as a function and returns the result. /// The '_this' property is the "this" object within the function when called. /// </summary> public virtual InternalHandle Call(string functionName, InternalHandle _this, params InternalHandle[] args) { return(_Handle.Call(functionName, _this, args)); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls the V8 'Set()' function on the underlying native object. /// Returns true if successful. /// </summary> /// <param name="attributes">Flags that describe the property behavior. They must be 'OR'd together as needed.</param> public virtual bool SetProperty(string name, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.None) { return(_Handle.SetProperty(name, value, attributes)); }
public override bool SetProperty(int index, InternalHandle value) { var result = IndexedPropertySetter(index, value); if (result.IsUndefined) return base.SetProperty(index, value); return true; }
public virtual InternalHandle IndexedPropertySetter(int index, InternalHandle value) { var propertyName = index.ToString(); return NamedPropertySetter(ref propertyName, value); }
/// <summary> /// Creates an upgradable read lock handle. /// </summary> /// <returns>the upgradable read lock handle.</returns> public IUpgradableLockHandle UseUpgradableReadLock() => InternalHandle.CreateUpgradableWriteHandle(_rwLock);
/// <summary> /// Creates a read lock handle. /// </summary> /// <returns>the read lock handle</returns> public IDisposable UseReadLock() => InternalHandle.CreateReadHandle(_rwLock);
/// <summary> /// JavaScript callback. Returns the content of the current line. /// </summary> public InternalHandle GetCurrentLine( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { string txt = _editor.GetCurrentLine(); return engine.CreateValue(txt); }
/// <summary> /// Constructs a ReadValueId for the specified UA attribute. /// </summary> /// <param name="handle">The handle.</param> /// <param name="uaAttributeId">The ua attribute id.</param> /// <returns></returns> private ReadValueId Construct(InternalHandle handle, uint uaAttributeId) { ReadValueId readValueId = new ReadValueId(); readValueId.NodeId = handle.NodeId; readValueId.AttributeId = uaAttributeId; readValueId.Handle = handle; return readValueId; }
/// <summary> /// Gets the item handles. /// </summary> /// <param name="session">The session.</param> /// <param name="itemIds">The item ids.</param> /// <param name="clientHandles">The client handles.</param> /// <param name="validateOnly">if set to <c>true</c> handles are not created and item ids are only validated.</param> /// <returns>The handles containing any error information.</returns> public HdaItemHandle[] GetItemHandles(Session session, string[] itemIds, int[] clientHandles, bool validateOnly) { HdaItemHandle[] handles = new HdaItemHandle[itemIds.Length]; ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < itemIds.Length; ii++) { InternalHandle handle = new InternalHandle(); handles[ii] = handle; if (clientHandles != null) { handle.ClientHandle = clientHandles[ii]; } string itemId = itemIds[ii]; if (String.IsNullOrEmpty(itemId)) { handle.Error = ResultIds.E_INVALIDITEMID; continue; } // check if item has already been assigned. Item item = null; if (!validateOnly) { lock (m_lock) { if (m_items.TryGetValue(itemId, out item)) { handle.NodeId = item.NodeId; handle.ServerHandle = ++m_lastServerHandle; handle.Item = item; item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); continue; } } } // create a new item. handle.Item = item = new Item(); item.ItemId = itemId; handle.Error = ResultIds.S_OK; // assume valid for no - set to an error when detected. handle.NodeId = item.NodeId = m_mapper.GetRemoteNodeId(itemId); nodesToRead.Add(Construct(handle, Attributes.UserAccessLevel)); nodesToRead.Add(Construct(handle, Attributes.DisplayName)); nodesToRead.Add(Construct(handle, Attributes.Description)); nodesToRead.Add(Construct(handle, Attributes.DataType)); nodesToRead.Add(Construct(handle, Attributes.ValueRank)); nodesToRead.Add(Construct(handle, Attributes.Historizing)); } // check if nothing to do. if (nodesToRead.Count == 0) { return handles; } DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; // read values from the UA server. session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out values, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // assign a local handle to all valid items. NodeIdCollection nodesToRegister = new NodeIdCollection(); List<InternalHandle> items = new List<InternalHandle>(); for (int ii = 0; ii < nodesToRead.Count; ii++) { InternalHandle handle = (InternalHandle)nodesToRead[ii].Handle; DataValue value = values[ii]; Item item = handle.Item; // check status codes. if (StatusCode.IsBad(value.StatusCode)) { // description is an optional attribute. if (nodesToRead[ii].AttributeId != Attributes.Description) { handle.Error = ResultIds.E_UNKNOWNITEMID; } continue; } // check access level. if (nodesToRead[ii].AttributeId == Attributes.UserAccessLevel) { byte accessLevel = value.GetValue<byte>(AccessLevels.None); if ((accessLevel & AccessLevels.HistoryRead) == 0) { handle.Error = ResultIds.E_UNKNOWNITEMID; continue; } } // save attribute. switch (nodesToRead[ii].AttributeId) { case Attributes.DisplayName: { item.DisplayName = value.GetValue<LocalizedText>(null); break; } case Attributes.Description: { item.Description = value.GetValue<LocalizedText>(null); break; } case Attributes.DataType: { item.DataType = value.GetValue<NodeId>(null); break; } case Attributes.ValueRank: { item.ValueRank = value.GetValue<int>(ValueRanks.Scalar); break; } case Attributes.Historizing: { item.Historizing = value.GetValue<bool>(false); break; } } // should have all item metadata when processing the historizing attribute result. if (nodesToRead[ii].AttributeId == Attributes.Historizing) { // check for a fatal error with one or more mandatory attributes. if (handle.Error != ResultIds.S_OK) { continue; } BuiltInType builtInType = DataTypes.GetBuiltInType(item.DataType, session.TypeTree); item.RemoteType = new TypeInfo(builtInType, item.ValueRank); if (!validateOnly) { nodesToRegister.Add(item.NodeId); items.Add(handle); lock (m_lock) { m_items[handle.Item.ItemId] = handle.Item; handle.ServerHandle = ++m_lastServerHandle; handle.NodeId = handle.Item.NodeId; handle.Item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); } } } } return handles; }
/// <summary> /// JavaScript callback. Creates absolute path by concatenating two arguments. /// </summary> public InternalHandle CreatePath( V8Engine engine, bool isConstructorCall, InternalHandle self, params InternalHandle[] args) { if (args.Length != 2) { this.TraceError("IEmmetFile createPath called with invalid number of arguments."); return engine.CreateValue(false); } string parent = args[0].AsString; string fileName = args[1].AsString; if (Path.HasExtension(parent)) parent = Path.GetDirectoryName(parent); return engine.CreateValue(Path.Combine(parent, fileName)); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls the V8 'Set()' function on the underlying native object. /// Returns true if successful. /// </summary> /// <param name="attributes">Flags that describe the property behavior. They must be 'OR'd together as needed.</param> public virtual bool SetProperty(string name, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.None) { return _Handle._Handle.SetProperty(name, value, attributes); }
/// <summary> /// JavaScript callback. Returns current editor's file path. /// </summary> public InternalHandle GetFilePath( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { // As of version 1.3 this callback is required only for actions with external images that we don't // support. return engine.CreateNullValue(); }
/// <summary> /// JavaScript callback. Returns current selection. /// </summary> public InternalHandle GetSelection( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { string selection = _editor.GetSelection(); if (string.IsNullOrEmpty(selection)) return engine.CreateValue(string.Empty); return engine.CreateValue(selection); }
/// <summary> /// JavaScript callback. Asks user to enter something. /// </summary> public InternalHandle Prompt( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { string input = _editor.Prompt(); if (string.IsNullOrWhiteSpace(input)) return engine.CreateNullValue(); return engine.CreateValue(input); }
public JSProperty(TValueSource source, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.None) : this(source, attributes) { _Value.Set(value); }
/// <summary> /// Reads the current values for the specified attributes. /// </summary> /// <param name="session">The session.</param> /// <param name="itemHandle">The item handle.</param> /// <param name="attributeIds">The attribute ids.</param> /// <returns></returns> public DaValue[] ReadCurrentValues(Session session, HdaItemHandle itemHandle, uint[] attributeIds) { DaValue[] results = new DaValue[attributeIds.Length]; // check handle. InternalHandle handle = itemHandle as InternalHandle; if (handle == null) { for (int ii = 0; ii < results.Length; ii++) { results[ii] = new DaValue(); results[ii].Error = ResultIds.E_INVALIDHANDLE; } return(results); } // look up the supported attributes for an item. ReadValueIdCollection supportedAttributes = handle.Item.SupportedAttributes; if (supportedAttributes == null) { handle.Item.SupportedAttributes = supportedAttributes = GetAvailableAttributes(session, handle.NodeId); } // build list of values to read. ReadValueIdCollection valuesToRead = new ReadValueIdCollection(); List <int> indexes = new List <int>(); for (int ii = 0; ii < attributeIds.Length; ii++) { ReadValueId valueToRead = GetReadValueId(supportedAttributes, attributeIds[ii]); if (valueToRead == null) { results[ii] = new DaValue(); results[ii].Error = ResultIds.E_INVALIDATTRID; continue; } valuesToRead.Add(valueToRead); indexes.Add(ii); // need to fetch the value rank as well. if (attributeIds[ii] == Constants.OPCHDA_DATA_TYPE) { valuesToRead.Add(GetReadValueId(supportedAttributes, ComHdaProxy.INTERNAL_ATTRIBUTE_VALUE_RANK)); indexes.Add(-1); } } // nothing to do. if (valuesToRead.Count == 0) { return(results); } // read values from the UA server. DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; session.Read( null, 0, TimestampsToReturn.Neither, valuesToRead, out values, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(values, valuesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead); // assign a local handle to all valid items. for (int ii = 0; ii < valuesToRead.Count; ii++) { int index = indexes[ii]; uint attributeId = (uint)valuesToRead[ii].Handle; // check for values which are combined with other values to create the value (e.g. ValueRank). if (index == -1) { continue; } results[index] = GetAttributeValue(session, attributeId, values, ii); // only support current value for now. if (results[index].Error == ResultIds.S_OK) { results[index].Error = ResultIds.S_CURRENTVALUE; } } return(results); }
/// <summary> /// Calls the native side to invoke the function associated with this managed function wrapper. /// The '_this' property is the "this" object within the function when called. /// <para>Note: This method simply calls 'Handle.Call()' without a function name.</para> /// </summary> public override InternalHandle Call(InternalHandle _this, params InternalHandle[] args) { return _Handle._Handle._Call(null, _this, args); }
/// <summary> /// JavaScript callback. Returns current output profile name (see profile module). In most cases, /// this method should return <code>null</code> and let Emmet guess best profile name for current /// syntax and user data. In case you’re using advanced editor with access to syntax scopes (like /// Sublime Text 2), you can return syntax name for current scope. For example, you may return /// `line` profile when editor caret is inside string of programming language. /// </summary> public InternalHandle GetProfileName( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { // Let Emmet engine detect profile return engine.CreateNullValue(); }
// (Get an object from an internal handle [value type] if the handle represents a managed V8 object, otherwise just return the internal handle as an object) static object _GetObjectOrHandle(InternalHandle h) => h.HasObject ? h.Object : (Handle)h;
/// <summary> /// Creates a write lock handle. /// </summary> /// <returns>the write lock handle</returns> public IDisposable UseWriteLock() => InternalHandle.CreateWriteHandle(_rwLock);
/// <summary> /// JavaScript callbacks. Returns the content of the current editor window. /// </summary> public InternalHandle GetContent( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { return engine.CreateValue(_editor.GetContent()); }
public virtual InternalHandle NamedPropertySetter(ref string propertyName, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.Undefined) { if (_Proxy != this) { var result = ((IV8ManagedObject)_Proxy).NamedPropertySetter(ref propertyName, value, attributes); if (!result.IsUndefined) return result; } var jsVal = this[propertyName]; if (jsVal.Value.IsEmpty) this[propertyName] = jsVal = new JSProperty(value, attributes != V8PropertyAttributes.Undefined ? attributes : V8PropertyAttributes.None); else { if (attributes != V8PropertyAttributes.Undefined) { jsVal.Attributes = attributes; jsVal.Value = value; // (note: updating attributes automatically assumes writable access) } else if ((jsVal.Attributes & V8PropertyAttributes.ReadOnly) == 0) jsVal.Value = value; } return jsVal.Value; }
/// <summary> /// Calls the V8 'Set()' function on the underlying native object. /// Returns true if successful. /// </summary> /// <param name="attributes">Flags that describe the property behavior. They must be 'OR'd together as needed.</param> public virtual bool SetProperty(string name, InternalHandle value, V8PropertyAttributes attributes) { return HandleInternal.HandleInternal.SetProperty(name, value, attributes); }
// -------------------------------------------------------------------------------------------------------------------- // Since some base methods operate on object properties, and the properties exist on this managed object, we override // them here to speed things up. public override bool SetProperty(string name, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.None) { var result = NamedPropertySetter(ref name, value, attributes); if (result.IsUndefined) return base.SetProperty(name, value, attributes); // (if this virtual override fails to set the property, try to do it via the base [directly on the native object]) return true; }
/// <summary> /// Calls the V8 'Set()' function on the underlying native object. /// Returns true if successful. /// </summary> public virtual bool SetProperty(Int32 index, InternalHandle value) { return HandleInternal.HandleInternal.SetProperty(index, value); }
/// <summary> /// JavaScript callback. Replace editor's content or it's part (from <code>start</code> to /// <code>end</code> index). If <code>value</code> contains <code>caret_placeholder</code>, the editor /// will put caret into this position. If you skip <code>start</code> and <code>end</code> arguments, /// the whole target's content will be replaced with <code>value</code>. /// If you pass <code>start</code> argument only, the <code>value</code> will be placed at /// <code>start</code> string index of current content. /// If you pass <code>start</code> and <code>end</code> arguments, the corresponding substring of /// current target's content will be replaced with <code>value</code>. /// </summary> public InternalHandle ReplaceContent( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { string rawContent = args[0].AsString; int regionStart = args.Length > 1 ? args[1].AsInt32 : -1; int regionLength = args.Length > 2 ? args[2].AsInt32 - regionStart : 0; bool indentContent = args.Length == 4 ? args[3].AsBoolean : true; this.Trace($"Received new content for the editor: {rawContent}"); // Extract tab stops placeholders from the specified content. var tabStops = TabStopsParser.ParseContent(engine, rawContent); _editor.ReplaceContentRange(tabStops.Content, regionStart, regionStart + regionLength); if (null != tabStops.TabStops) { Range[] tabStopRanges = tabStops.TabStops; // Tab stop offsets are relative to the newly generated content ranges, we need to convert // them to the document-wide offsets. if (regionStart > 0) { tabStopRanges = tabStopRanges.Select( item => new Range(item.Start + regionStart, item.End + regionStart)).ToArray(); } _editor.TrackTabStops(tabStopRanges, tabStops.TabStopGroups); } if (indentContent) _editor.FormatRegion(regionStart, regionStart + tabStops.Content.Length); return engine.CreateValue(true); }
public InternalHandle CreateConnection(V8Engine engine, bool isConstructCall, InternalHandle _this, InternalHandle[] args) { try { if (args.Length >= 1) { var profileName = args[0].AsString; InternalHandle callback = (args.Length == 2 ? args[1].KeepAlive() : null); if (!string.IsNullOrEmpty(profileName)) { if (callback != null && callback.IsFunction) { new Task(() => { try { callback.StaticCall(Engine.CreateValue(new ConnectionHelper(profileName))); } catch (Exception ex) { Log.Trace(ex.Message, ex.StackTrace, true); } }).Start(); } else { try { return(Engine.CreateValue(new ConnectionHelper(profileName))); } catch (Exception ex) { Log.Trace(ex.Message, ex.StackTrace, true); } } } } } catch (Exception ex) { Log.Trace(ex.Message, ex.StackTrace, true); } return(null); }
/// <summary> /// Calls the V8 'Set()' function on the underlying native object. /// Returns true if successful. /// </summary> /// <param name="index"> Zero-based index to set. </param> /// <param name="value"> The value to set. </param> /// <param name="attributes"> /// (Optional) Flags that describe the property behavior. They must be 'OR'd together as needed. /// <para>Warning: V8 does not support setting attributes using numerical indexes. If you set an attribute, the given /// value is converted to a string, and a named property setter will be used instead. </para> /// </param> public virtual bool SetProperty(Int32 index, InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.Undefined) { return(_Handle.SetProperty(index, value, attributes)); }
/// <summary> /// JavaScript callback. Set new caret position. /// </summary> public InternalHandle SetCarretPos( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { _editor.SetCaretPosition(args[0].AsInt32); return engine.CreateValue(true); }
/// <summary> /// Calls the underlying object as a function. /// The '_this' parameter is the "this" reference within the function when called. /// </summary> public virtual InternalHandle Call(InternalHandle _this, params InternalHandle[] args) { return(_Handle.Call(_this, args)); }
// -------------------------------------------------------------------------------------------------------------------- // Since some base methods operate on object properties, and the properties exist on this managed object, we override // them here to speed things up. public override bool SetProperty(string name, InternalHandle value) { return SetProperty(name, value, V8PropertyAttributes.None); }
public JSProperty(InternalHandle value, V8PropertyAttributes attributes = V8PropertyAttributes.None) : this(default(TValueSource), value, attributes) { }
public override bool SetProperty(string name, InternalHandle value, V8PropertyAttributes attributes) { var result = NamedPropertySetter(ref name, value, attributes); return !result.IsUndefined || base.SetProperty(name, value, attributes); }
/// <summary> /// Gets the item handles. /// </summary> /// <param name="session">The session.</param> /// <param name="itemIds">The item ids.</param> /// <param name="clientHandles">The client handles.</param> /// <param name="validateOnly">if set to <c>true</c> handles are not created and item ids are only validated.</param> /// <returns>The handles containing any error information.</returns> public HdaItemHandle[] GetItemHandles(Session session, string[] itemIds, int[] clientHandles, bool validateOnly) { HdaItemHandle[] handles = new HdaItemHandle[itemIds.Length]; ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < itemIds.Length; ii++) { InternalHandle handle = new InternalHandle(); handles[ii] = handle; if (clientHandles != null) { handle.ClientHandle = clientHandles[ii]; } string itemId = itemIds[ii]; if (String.IsNullOrEmpty(itemId)) { handle.Error = ResultIds.E_INVALIDITEMID; continue; } // check if item has already been assigned. Item item = null; if (!validateOnly) { lock (m_lock) { if (m_items.TryGetValue(itemId, out item)) { handle.NodeId = item.NodeId; handle.ServerHandle = ++m_lastServerHandle; handle.Item = item; item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); continue; } } } // create a new item. handle.Item = item = new Item(); item.ItemId = itemId; handle.Error = ResultIds.S_OK; // assume valid for no - set to an error when detected. handle.NodeId = item.NodeId = m_mapper.GetRemoteNodeId(itemId); nodesToRead.Add(Construct(handle, Attributes.UserAccessLevel)); nodesToRead.Add(Construct(handle, Attributes.DisplayName)); nodesToRead.Add(Construct(handle, Attributes.Description)); nodesToRead.Add(Construct(handle, Attributes.DataType)); nodesToRead.Add(Construct(handle, Attributes.ValueRank)); nodesToRead.Add(Construct(handle, Attributes.Historizing)); } // check if nothing to do. if (nodesToRead.Count == 0) { return(handles); } DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; // read values from the UA server. session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out values, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // assign a local handle to all valid items. NodeIdCollection nodesToRegister = new NodeIdCollection(); List <InternalHandle> items = new List <InternalHandle>(); for (int ii = 0; ii < nodesToRead.Count; ii++) { InternalHandle handle = (InternalHandle)nodesToRead[ii].Handle; DataValue value = values[ii]; Item item = handle.Item; // check status codes. if (StatusCode.IsBad(value.StatusCode)) { // description is an optional attribute. if (nodesToRead[ii].AttributeId != Attributes.Description) { handle.Error = ResultIds.E_UNKNOWNITEMID; } continue; } // check access level. if (nodesToRead[ii].AttributeId == Attributes.UserAccessLevel) { byte accessLevel = value.GetValue <byte>(AccessLevels.None); if ((accessLevel & AccessLevels.HistoryRead) == 0) { handle.Error = ResultIds.E_UNKNOWNITEMID; continue; } } // save attribute. switch (nodesToRead[ii].AttributeId) { case Attributes.DisplayName: { item.DisplayName = value.GetValue <LocalizedText>(null); break; } case Attributes.Description: { item.Description = value.GetValue <LocalizedText>(null); break; } case Attributes.DataType: { item.DataType = value.GetValue <NodeId>(null); break; } case Attributes.ValueRank: { item.ValueRank = value.GetValue <int>(ValueRanks.Scalar); break; } case Attributes.Historizing: { item.Historizing = value.GetValue <bool>(false); break; } } // should have all item metadata when processing the historizing attribute result. if (nodesToRead[ii].AttributeId == Attributes.Historizing) { // check for a fatal error with one or more mandatory attributes. if (handle.Error != ResultIds.S_OK) { continue; } BuiltInType builtInType = DataTypes.GetBuiltInType(item.DataType, session.TypeTree); item.RemoteType = new TypeInfo(builtInType, item.ValueRank); if (!validateOnly) { nodesToRegister.Add(item.NodeId); items.Add(handle); lock (m_lock) { m_items[handle.Item.ItemId] = handle.Item; handle.ServerHandle = ++m_lastServerHandle; handle.NodeId = handle.Item.NodeId; handle.Item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); } } } } return(handles); }
public SuspendedHandleContext(string path, InternalHandle handle) { this.path = path; this.handle = handle; }
public virtual InternalHandle NamedPropertySetter(ref string propertyName, InternalHandle value) { return NamedPropertySetter(ref propertyName, value, V8PropertyAttributes.Undefined); }
/// <summary> /// JavaScript callback. Returns current editor's syntax mode. /// </summary> public InternalHandle GetSyntax( V8Engine engine, bool isConstructCall, InternalHandle self, params InternalHandle[] args) { return engine.CreateValue(_syntax); }
/// <summary> /// If the function object has a function property in itself (usually considered a static property in theory), you can use this to invoke it. /// </summary> public override InternalHandle Call(string functionName, InternalHandle _this, params InternalHandle[] args) { if (functionName.IsNullOrWhiteSpace()) throw new ArgumentNullException("functionName (cannot be null, empty, or only whitespace)"); return _Handle.Call(functionName, _this, args); // (if a function name exists, then it is a request to get a property name on the object as a function [and not to use this function object itself]) }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls an object property with a given name on a specified object as a function and returns the result. /// The '_this' property is the "this" object within the function when called. /// </summary> public virtual InternalHandle Call(string functionName, InternalHandle _this, params InternalHandle[] args) { return HandleInternal.HandleInternal.Call(functionName, _this, args); }
// (For calling '.KeepTrack()' on an engine call expression that returns an 'InternalHandle' in order to dispose of it on the native side when done) static Expression _KeepTrack(InternalHandle currentHandle, Expression internalHandleValue) => Expression.Call(internalHandleValue, ((Func <InternalHandle>)currentHandle.KeepTrack).Method);
/// <summary> /// Calls the underlying object as a function. /// The '_this' parameter is the "this" reference within the function when called. /// </summary> public virtual InternalHandle Call(InternalHandle _this, params InternalHandle[] args) { return HandleInternal.HandleInternal.Call(_this, args); }