e10s - I want to get from nsIObserver-nsIHttpChannel-nsIDOMWindow-nsIDOMDocument. How can I do it? - e10s

My addon worked on FF41. Now I want to migrate on e10s. Use Firefox developer edition v43.
The example observer (c++).
NS_IMETHODIMP CFFObserver::Observe( nsISupports* aSubject, const char* aTopic, const char16_t* aData )
{ .........
if ( lstrcmpA( aTopic, "http-on-modify-request" ) == 0 )
{
CFFObserver::onSending( aSubject );
} ..........
}
void CFFObserver::onSending( nsISupports* IHttpChannel )
{
..............
nsISupports* IDOMWindowOwner = m_gate.Channel_GetOwnerWindow( IHttpChannel );
.................
}
The example JS helper.
Channel_GetOwnerWindow:
function( objChannel ) // This option does not worked in v43[e10s]; <br>
{
try
{
var notificationCallbacks = objChannel.QueryInterface(Components.interfaces.nsIHttpChannel).notificationCallbacks;
if ( !notificationCallbacks )
{
var loadGroup = objChannel.QueryInterface(Components.interfaces.nsIRequest).loadGroup.notificationCallbacks;
if ( loadGroup ) notificationCallbacks = loadGroup.notificationCallbacks;
}
if ( notificationCallbacks )
{
return notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow)
.QueryInterface(Components.interfaces.nsISupports);
}
}
catch ( err )
{
this.ErrorOut( err );
}
return null;
}
Below code works but I cannot get document from getting nsIDOMWindow.
......
objWindow.QueryInterface(Components.interfaces.nsIDOMWindow).document.QueryInterface(Components.interfaces.nsISupports)
is error - no interface....
Channel_GetOwnerWindow:
function( objChannel )
{
try
{
return objChannel.QueryInterface(Components.interfaces.nsIHttpChannel)
.notificationCallbacks
.getInterface(Components.interfaces.nsILoadContext)
.topFrameElement
.QueryInterface(Components.interfaces.nsISupports);
}
catch ( err )
{
this.ErrorOut( err );
}
return null;
}
Help me please resolve this problem. Thanks.

Resolved!
var browser = objChannel.QueryInterface(Components.interfaces.nsIHttpChannel)
.notificationCallbacks
.getInterface(Components.interfaces.nsILoadContext).topFrameElement;
var window = browser.contentWindow.QueryInterface(Components.interfaces.nsISupports);

Related

How to reference multiple libs with same functions and switch between them inline in Go

I am wondering how I can do something similar to this. I currently have multiple packages with that same structure and functions but they actually retrieve values from multiple APIs. I am also loading in a config that has an array with parameters to use one of those packages per array item.
I am wondering how I can create a variable that uses one of those packages based on the config value. Hopefully this is clear enough. Here is pseudo code that I have written up to explain. Thanks in advance
package main
import (
"errors"
"flag"
"os"
"project/lib"
"project/morelib"
"project/extralib"
"fmt"
"math"
"math/rand"
"time"
)
func stuff(info RunInfo) (err error) {
apiKey:= "stuff1" // actually in the config
apiSecret := "stuff2" // actually in the config
variable := lib.New(apiKey, apiSecret) //returns *Lib struct
//this is where I have to comment out the other libs and uncomment them as needed
// variable := morelib.New(apiKey, apiSecret)
// variable := extralib.New(apiKey, apiSecret)
//trying to switch between libraries like this or in a switch statement
if info.libname == "lib"{
variable = lib.New(apiKey, apiSecret) //.New("", "") returns *Lib struct
}else if info.libname == "morelib"{
variable = morelib.New(apiKey, apiSecret) //.New("", "") returns *MoreLib struct
}else if info.libname == "extralib"{
variable = extralib.New(apiKey, apiSecret) //.New("", "") returns *ExtraLib struct
}else{
err = errors.New("there was an error with the value.....")
return err
}
mystuffs, err := variable.GetBalance("USD")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("mystuff value: %v", mystuffs.value)
return
}
type RunInfo struct{
libname string
//other stuff
}
func main() {
//load from config with array
config := config.Load()
for i:=0; i<compare; i++{
var runInfo RunInfo
runInfo.libname = config.libname
stuff(runInfo)
}
}
pseudo lib code:
func New(apiKey, apiSecret string) *Lib {
client := NewClient(apiKey, apiSecret)
return &Lib{client}
}
func NewClient(apiKey, apiSecret string) (c *client) {
return &client{apiKey, apiSecret, &http.Client{}, false}
}
type Lib struct {
client *client
}
type client struct {
apiKey string
apiSecret string
httpClient *http.Client
debug bool
}
func (b *Lib) GetBalance(currency string) (balance Balance, err error) {
payload, err := json.Marshal(BalanceParams{Currency: currency})
if err != nil {
return
}
r, err := b.client.do("POST", "GetBalance", string(payload), true)
if err != nil {
return
}
var response jsonResponse
if err = json.Unmarshal(r, &response); err != nil {
return
}
if err = handleErr(response); err != nil {
return
}
err = json.Unmarshal(response.Result, &balance)
return
}
Use and if statement as in the question, a switch statement or a map.
I assume that the type returned by the New function is the following interface:
type GetStuffer interface
GetStuff(string) (Stuff, error)
}
The switch statement is:
var variable GetStuffer
switch info.CompareVal {
case "lib":
variable = lib.New(string1, string2)
case "morelib":
variable = morelib.New(string1, string2)
case "extralib":
variable = extralib.New(string1, string2)
default:
return errors.New("there was an error with the value.....")
}
mystuffs, err := variable.GetMyStuff()
if err != nil {
fmt.Println(err)
return
}
For the map, initialize a package level variable with the map:
var m = map[string]func(string,string) GetStuffer {
"lib": lib.New,
"morelib": morelib.New,
"extralib": extralib.New,
}
and use it like this:
fn := m[info.CompareValue]
if m == nil {
return errors.New("there was an error with the value.....")
}
variable := fn(string1, string2)
mystuffs, err := variable.GetMyStuff()
if err != nil {
fmt.Println(err)
return
}
If the assumption above about the return type is not correct, then there are two options. The first and likely the simplest is to modify New functions to return type GetStuffer. If that's not possible, then write little adaptor functions:
var m = map[string]func(string,string) GetStuffer {
"lib":func(s1, s2 string) GetStuffer { return lib.New(s1, s2) }
"morelib":func(s1, s2 string) GetStuffer { return morelib.New(s1, s2) }
"extralib":func(s1, s2 string) GetStuffer { return extralib.New(s1, s2) }
}
Why don't you define an interface that's only one function? In your example would be
type Stuffer interface {
GetMyStuff(string) (Stuff, error)
}
Then you declare your variable as type Stuffer.

THREE.JS: How can I check that Group of objects was rendered?

I need make the screenshot after group of my objects was added and rendered on scene;
I tried add eventListener to "added" event, which triggered when object was added to scene, but it still not rendered and as result it doesn't exist on screenshot;
add: function ( object ) {
if ( arguments.length > 1 ) {
for ( var i = 0; i < arguments.length; i ++ ) {
this.add( arguments[ i ] );
}
return this;
}
if ( object === this ) {
console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
return this;
}
if ( (object && object.isObject3D) ) {
if ( object.parent !== null ) {
object.parent.remove( object );
}
object.parent = this;
object.dispatchEvent( { type: 'added' } );
object.dispatchEvent( { type: 'added' } );
this.children.push( object );
} else {
console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
}
return this;
},
As I understand it doesn't help me, because render is called after adding objects to scene and creating screenshot, that's why this subscribe does not help me;
Here example of code:
let group = new THREE.Group();
// here some objects were added to group
scene.add(group);
window.open(renderer.domElement.toDataURL('image/png'), 'screenshot');
Any suggestions?

Set function not changing contract's state

I have the following contract
pragma solidity ^0.4.11;
contract Personal {
/* Constructor */
address owner;
uint record;
function Personal() {
owner = msg.sender;
}
function remove() {
if (msg.sender == owner) {
// Suicide and send funds to owner
selfdestruct(owner);
}
}
function getRecord() constant returns (uint) {
if (msg.sender == owner) {
return (record);
}
}
function setRecord(uint newRecord) {
if (msg.sender == owner) {
record = newRecord;
}
}
}
deployed at address 0x842CF8023DAF79b0f3a39154788C7E9D4862b986 in the Rinkeby network. I tried calling the setRecord function using this code
function setRecord(publicAddress, contractAddress, contractName) {
// Get the contract code from contracts
const input = fs.readFileSync('contracts/' + contractName + '.sol').toString();
const output = solc.compile(input);
// The trailing ':' is needed otherwise it crashes
const bytecode = output.contracts[':' + contractName].bytecode;
const abi = JSON.parse(output.contracts[':' + contractName].interface);
const contract = web3.eth.contract(abi).at(contractAddress);
contract.setRecord(4398, {from: publicAddress}, (err, res) => {
// Log transaction to explore
console.log('tx: ' + res);
});
}
passing it the correct input values. This generated the transaction 0xc65404af2e58df978e80c4c82f78a0b645bca710b33a28d2cf07e1e331fee60a. However, when I call getRecord now, I still get back
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }
I know this must be converted from BigNumber as explained here but that just returns 0. Why is this?
It's my first time trying this so apologies in advance if it's something obvious.

Quill.js and zombie.js

Trying to test quill.js editor (contenteditable div) in the zombie.js headless browser.
Complaining about document.getSelection missing
Complaining about document.createTreeWalker missing
Doesn't seem to respond if I manually dispatch a change event using the DOM node of the editor.
Anyone know how to make this work?
Ok, here's what I've found:
document.getSelection isn't supported by the current (old) version of jsdom which zombie.js uses. I've had to monkey-patch it for now. There is a pending PR for zombie.js that should update jsdom to a later version where these are available: https://github.com/assaf/zombie/issues/939
document.createTreeWalker - same
turns out that quill.js is listening for "keyup" or "keydown" rather than "change", so need to dispatch those instead.
Below are some terrible monkey-patches of the missing DOM methods which turn out to be adequate for testing the bare minimum of quill.js:
var zombie = require( "zombie" );
zombie.Pipeline.addHandler(function(browser, request, response) {
browser.document.getSelection = browser.window.getSelection = function() {
console.warn( "getSelection called - monkey-patched, incorrect implementation" );
return null;
};
browser.document.createTreeWalker = function( x ) {
console.warn( "createTreeWalker called - monkey-patched, incorrect implementation" );
return {
currentNode: x,
nextNode: function() {
if( this.currentNode.childNodes && this.currentNode.childNodes.length ) {
this.currentNode = this.currentNode.childNodes[ 0 ];
} else if( this.currentNode.nextSibling ) {
this.currentNode = this.currentNode.nextSibling;
} else if( this.currentNode.parentNode ) {
this.currentNode = this.currentNode.parentNode.nextSibling;
}
return this.currentNode || null;
}
};
};
return response;
} );

properties cannot be accessed in error handler

Two questions:
Looking at the highlighted line in https://github.com/bwu-dart/bwu_datagrid/blob/master/example/src/composite_editor_item_details/app_element.dart#L120
1) why does the line
var idx = e.validationResults.errors.length;
always throws an error?
Exception: Uncaught Error: The null object does not have a getter 'length'.
NoSuchMethodError: method not found: 'length'
Receiver: null
Arguments: []
Stack Trace:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1 validationErrorHandler (http://localhost:8080/epimss_design.html.12.dart:184:42)
#2 _RootZone.runUnaryGuarded (dart:async/zone.dart:1020)
#3 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341)
#4 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:270)
#5 _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:346)
#6 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:237)
#7 EventBus.fire (package:bwu_datagrid/core/event_bus.dart:61:19)
#8 _commitCurrentEdit (package:bwu_datagrid/bwu_datagrid.dart:3626:25)
#9 EditorLock.commitCurrentEdit (package:bwu_datagrid/core/range.dart:235:82)
#10 BwuDatagrid._commitEditAndSetFocus (package:bwu_datagrid/bwu_datagrid.dart:3045:40)
#11 _handleKeyDown (package:bwu_datagrid/bwu_datagrid.dart:2632:39)
The same thing happens for other properties as well such as field and column etc.
2) How can I test that the validationResult returns true? The error handler seems to only fires when there is an ValidationError.
My validator is shown below
import 'package:bwu_datagrid/datagrid/helpers.dart' show Column, GridOptions,
MapDataItem, MapDataItemProvider;
import 'package:bwu_datagrid/bwu_datagrid.dart' show BwuDatagrid;
import 'package:bwu_datagrid/formatters/formatters.dart' show CheckmarkFormatter;
import 'package:bwu_datagrid/editors/editors.dart' show CheckboxEditor, EditorArgs,
IntegerEditor, TextEditor;
import 'package:bwu_datagrid/core/core.dart' show AddNewRow, ActiveCellChanged,
ItemBase, ValidationError;
import 'package:bwu_datagrid/plugins/row_selection_model.dart' show RowSelectionModel;
import 'package:epimss_podo/reg.dart' show Email, EMAIL_FORM_EVENT;
import 'package:epimss_shared/shared.dart' show toggleCoreCollapse, onBwuCellChangeHandler;
import 'package:epimss_shared/validators.dart' show BwuRequiredEmailValidator,
BwuRequiredNounValidator;
Custom validators:
const String REQUIRED_EMAIL_REGEX = r"\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b";
const String REQUIRED_NOUN_REGEX = r"\b[a-z'-]{2,}\b";
final RegExp _requiredNounValidator = new RegExp( REQUIRED_NOUN_REGEX, caseSensitive: false );
bool isRequiredNounValid( String property ) =>
_requiredNounValidator.hasMatch( property );
final RegExp _requiredEmailPropertyValidator = new RegExp( REQUIRED_EMAIL_REGEX, caseSensitive: false );
bool isRequiredEmailPropertyValid( String property ) => _requiredEmailPropertyValidator.hasMatch( property );
class BwuRequiredEmailValidator extends bwu.Validator {
bwu.ValidationResult call( dynamic value ) {
if ( isRequiredEmailPropertyValid( value ) ) {
return new bwu.ValidationResult( true );
} else {
return new bwu.ValidationResult( false, 'Valid email address required.' );
}
}
}
class BwuRequiredNounValidator extends bwu.Validator {
bwu.ValidationResult call( dynamic value ) {
if ( isRequiredNounValid( value) ) {
return new bwu.ValidationResult( true );
} else {
return new bwu.ValidationResult( false, 'Valid noun is required.' );
}
}
}
Validation error handler:
void validationErrorHandler( ValidationError e ) {
//print ( e.validationResults.errors.length );
print ( e.column.field );
if ( e.validationResults.isValid )
print( 'retVal is true' );
else
print( 'retVal is false' );
errorMsg = e.validationResults.message;
var editor = e.editor;
print ( 'valResult valid |' + e.validationResults.isValid.toString() );
var result = e.validationResults;
if ( e.validationResults.isValid ) {
errorMsg = 'EMAIL';
} else {
errorMsg = result.message;
}
print( editor.runtimeType ); // aslways print TextEditor
if ( editor != null ) {
//var colId = editor.column.id;
if ( editor is TypeEditor ) {
email.isTypeValid = true;
}
if ( editor is AddressEditor ) {
email.isAddressValid = false;
}
//print( encode ( email ) );
}
}
You get the exception because the field e.validationResults.errors is null.
You can't access the length property of null thus the exception is thrown.
The field errors is null because in this call
return new bwu.ValidationResult( false, 'Valid email address required.' );
you didn't pass a value for the optional errors parameter
class ValidationResult {
bool isValid = false;
String message;
List<ValidationErrorSource> errors;
ValidationResult(this.isValid, [this.message, this.errors]);
}
Hint:
As far as I know breakpoints don't work for code within <script> tags (I saw this in the example code I got in an email).
I therefore advise to move your code from the email_form.html file to a email_form.dart file.
Then you can use the debugger and investigate the values at runtime which also helps a lot to learn what others peoples code is actually doing.
Fire custom event from Editor
class AddressEditor extends bwu.TextEditor {
static const VALIDATION_SUCCEEDED = const EventType<ValidationError>(
'custom-validation-succeeded');
...
#override
bwu.ValidationResult validate() {
var result = super.validate();
args.grid.eventBus.fire(AddressEditor.VALIDATION_SUCCEEDED, new ValidationError(this,
editor: this,
cellNode: args.grid.getActiveCellNode(),
validationResults: result,
cell: args.grid.getActiveCell(),
column: column));
return result;
}
// you can register the same handler as for the validation error event
grid.eventBus.onEvent(AddressEditor.VALIDATION_SUCCEEDED).listen(validationErrorHandler);
I have not tried this code but it should work.

Resources