예제 #1
0
bool ClientApp::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  ASSERT(source_process == PID_BROWSER);

  bool handled = false;

  RenderDelegateSet::iterator it = render_delegates_.begin();
  for (; it != render_delegates_.end() && !handled; ++it) {
    handled = (*it)->OnProcessMessageReceived(this, browser, source_process,
                                              message);
  }

  if (handled)
    return true;

  // Execute the registered JavaScript callback if any.
  if (!callback_map_.empty()) {
    CefString message_name = message->GetName();
    CallbackMap::const_iterator it = callback_map_.find(
        std::make_pair(message_name.ToString(),
                       browser->GetIdentifier()));
    if (it != callback_map_.end()) {
      // Keep a local reference to the objects. The callback may remove itself
      // from the callback map.
      CefRefPtr<CefV8Context> context = it->second.first;
      CefRefPtr<CefV8Value> callback = it->second.second;

      // Enter the context.
      context->Enter();

      CefV8ValueList arguments;

      // First argument is the message name.
      arguments.push_back(CefV8Value::CreateString(message_name));

      // Second argument is the list of message arguments.
      CefRefPtr<CefListValue> list = message->GetArgumentList();
      CefRefPtr<CefV8Value> args =
          CefV8Value::CreateArray(static_cast<int>(list->GetSize()));
      SetList(list, args);
      arguments.push_back(args);

      // Execute the callback.
      CefRefPtr<CefV8Value> retval = callback->ExecuteFunction(NULL, arguments);
      if (retval.get()) {
        if (retval->IsBool())
          handled = retval->GetBoolValue();
      }

      // Exit the context.
      context->Exit();
    }
  }

  return handled;
}
예제 #2
0
 // Simple function for formatted output of a V8 value.
 void PrintValue(CefRefPtr<CefV8Value> value, std::stringstream &stream,
                 int indent)
 {
   std::stringstream indent_stream;
   for(int i = 0; i < indent; ++i)
     indent_stream << "  ";
   std::string indent_str = indent_stream.str();
   
   if(value->IsUndefined())
     stream << "(undefined)";
   else if(value->IsNull())
     stream << "(null)";
   else if(value->IsBool())
     stream << "(bool) " << (value->GetBoolValue() ? "true" : "false");
   else if(value->IsInt())
     stream << "(int) " << value->GetIntValue();
   else if(value->IsDouble())
     stream << "(double) " << value->GetDoubleValue();
   else if(value->IsString())
     stream << "(string) " << std::string(value->GetStringValue());
   else if(value->IsFunction())
     stream << "(function) " << std::string(value->GetFunctionName());
   else if(value->IsArray()) {
     stream << "(array) [";
     int len = value->GetArrayLength();
     for(int i = 0; i < len; ++i) {
       stream << "\n  " << indent_str.c_str() << i << " = ";
       PrintValue(value->GetValue(i), stream, indent+1);
     }
     stream << "\n" << indent_str.c_str() << "]";
   } else if(value->IsObject()) {
     stream << "(object) [";
     std::vector<CefString> keys;
     if(value->GetKeys(keys)) {
       for(size_t i = 0; i < keys.size(); ++i) {
         stream << "\n  " << indent_str.c_str() << keys[i].c_str() << " = ";
         PrintValue(value->GetValue(keys[i]), stream, indent+1);
       }
     }
     stream << "\n" << indent_str.c_str() << "]";
   }
 }
예제 #3
0
bool ClientApp::OnProcessMessageReceived(
        CefRefPtr<CefBrowser> browser,
        CefProcessId source_process,
        CefRefPtr<CefProcessMessage> message) {
    ASSERT(source_process == PID_BROWSER);

    bool handled = false;

    // Execute delegate callbacks.
    RenderDelegateSet::iterator it = render_delegates_.begin();
    for (; it != render_delegates_.end() && !handled; ++it) {
        handled = (*it)->OnProcessMessageReceived(this, browser, source_process, message);
    }

    if (!handled) {
        if (message->GetName() == "invokeCallback") {
            // This is called by the appshell extension handler to invoke the asynchronous 
            // callback function
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            int32 callbackId = messageArgs->GetInt(0);
                    
            CefRefPtr<CefV8Context> context = callback_map_[callbackId].first;
            CefRefPtr<CefV8Value> callbackFunction = callback_map_[callbackId].second;
            CefV8ValueList arguments;
            context->Enter();
            
            // Sanity check to make sure the context is still attched to a browser.
            // Async callbacks could be initiated after a browser instance has been deleted,
            // which can lead to bad things. If the browser instance has been deleted, don't
            // invoke this callback. 
            if (context->GetBrowser()) {
                for (size_t i = 1; i < messageArgs->GetSize(); i++) {
                    arguments.push_back(ListValueToV8Value(messageArgs, i));
                }
                
                callbackFunction->ExecuteFunction(NULL, arguments);
            }
            
            context->Exit();
            
            callback_map_.erase(callbackId);
        } else if (message->GetName() == "executeCommand") {
            // This is called by the browser process to execute a command via JavaScript
            // 
            // The first argument is the command name. This is required.
            // The second argument is a message id. This is optional. If set, a response
            // message will be sent back to the browser process.
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            CefString commandName = messageArgs->GetString(0);
            int messageId = messageArgs->GetSize() > 1 ? messageArgs->GetInt(1) : -1;
            bool handled = false;
            
            StContextScope ctx(browser->GetMainFrame()->GetV8Context());
            
            CefRefPtr<CefV8Value> global = ctx.GetContext()->GetGlobal();
            
            if (global->HasValue("brackets")) { 
                
                CefRefPtr<CefV8Value> brackets = global->GetValue("brackets");
                
                if (brackets->HasValue("shellAPI")) {
                    
                    CefRefPtr<CefV8Value> shellAPI = brackets->GetValue("shellAPI");
                    
                    if (shellAPI->HasValue("executeCommand")) {
                        
                        CefRefPtr<CefV8Value> executeCommand = shellAPI->GetValue("executeCommand");
                        
                        if (executeCommand->IsFunction()) {
                            
                            CefRefPtr<CefV8Value> retval;
                            CefV8ValueList args;
                            args.push_back(CefV8Value::CreateString(commandName));
                            
                            retval = executeCommand->ExecuteFunction(global, args);
                            
                            if (retval) {
                                handled = retval->GetBoolValue();
                            }
                        }
                    }
                }
            }
            
            // Return a message saying whether or not the command was handled
            if (messageId != -1) {
                CefRefPtr<CefProcessMessage> result = CefProcessMessage::Create("executeCommandCallback");
                result->GetArgumentList()->SetInt(0, messageId);
                result->GetArgumentList()->SetBool(1, handled);
                
                browser->SendProcessMessage(PID_BROWSER, result);
            }
        }
    }
    
    return handled;
}
예제 #4
0
void V8ValueAppendToCefListValue(CefRefPtr<CefV8Value> v8Value,
                                 CefRefPtr<CefListValue> listValue,
                                 int nestingLevel) {
    if (!v8Value->IsValid()) {
        DebugLog("V8ValueAppendToCefListValue(): IsValid() FAILED");
        return;
    }
    if (nestingLevel > 8) {
        DebugLog("V8ValueAppendToCefListValue(): WARNING: max nesting level (8) " \
                "exceeded");
        return;
    }
    if (v8Value->IsUndefined() || v8Value->IsNull()) {
        listValue->SetNull((int)listValue->GetSize());
    } else if (v8Value->IsBool()) {
        listValue->SetBool((int)listValue->GetSize(), v8Value->GetBoolValue());
    } else if (v8Value->IsInt()) {
        listValue->SetInt((int)listValue->GetSize(), v8Value->GetIntValue());
    } else if (v8Value->IsUInt()) {
        uint32 uint32_value = v8Value->GetUIntValue();
        CefRefPtr<CefBinaryValue> binaryValue = CefBinaryValue::Create(
            &uint32_value, sizeof(uint32_value));
        listValue->SetBinary((int)listValue->GetSize(), binaryValue);
    } else if (v8Value->IsDouble()) {
        listValue->SetDouble((int)listValue->GetSize(), v8Value->GetDoubleValue());
    } else if (v8Value->IsDate()) {
        // TODO: in time_utils.pyx there are already functions for
        // converting cef_time_t to python DateTime, we could easily
        // add a new function for converting the python DateTime to
        // string and then to CefString and expose the function using
        // the "public" keyword. But how do we get the cef_time_t
        // structure from the CefTime class? GetDateValue() returns
        // CefTime class.
        listValue->SetNull((int)listValue->GetSize());
    } else if (v8Value->IsString()) {
        listValue->SetString((int)listValue->GetSize(), v8Value->GetStringValue());
    } else if (v8Value->IsArray()) {
        // Check for IsArray() must happen before the IsObject() check.
        int length = v8Value->GetArrayLength();
        CefRefPtr<CefListValue> newListValue = CefListValue::Create();
        for (int i = 0; i < length; ++i) {
            V8ValueAppendToCefListValue(v8Value->GetValue(i), newListValue,
                    nestingLevel + 1);
        }
        listValue->SetList((int)listValue->GetSize(), newListValue);
    } else if (v8Value->IsFunction()) {
        // Check for IsFunction() must happen before the IsObject() check.
        if (CefV8Context::InContext()) {
            CefRefPtr<CefV8Context> context = \
                    CefV8Context::GetCurrentContext();
            CefRefPtr<CefFrame> frame = context->GetFrame();
            std::string strCallbackId = PutJavascriptCallback(frame, v8Value);
            /* strCallbackId = '####cefpython####' \
                               '{"what"=>"javascript-callback", ..}' */
            listValue->SetString((int)listValue->GetSize(), strCallbackId);
        } else {
            listValue->SetNull((int)listValue->GetSize());
            DebugLog("V8ValueAppendToCefListValue() FAILED: not in V8 context"
                    " , FATAL ERROR!");
        }
    } else if (v8Value->IsObject()) {
        // Check for IsObject() must happen after the IsArray()
        // and IsFunction() checks.
        listValue->SetDictionary((int)listValue->GetSize(),
                V8ObjectToCefDictionaryValue(v8Value, nestingLevel + 1));
    } else {
        listValue->SetNull((int)listValue->GetSize());
        DebugLog("V8ValueAppendToCefListValue() FAILED: unknown V8 type");
    }
}
예제 #5
0
bool CSJsUi::Execute(const CefString& name,  CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,  CefRefPtr<CefV8Value>& retval, CefString& exception)
{
    if (name == "startMove")
    {
        mWindow->StartMove();
		retval = CefV8Value::CreateNull();
		return true;
    }
    else if (name == "stopMove")
    {
        mWindow->StopMove();
		retval = CefV8Value::CreateNull();
		return true;        
    }
    else if (name == "startResize")
    {
        mWindow->StartResize();
		retval = CefV8Value::CreateNull();
		return true;            
    }
    else if (name == "stopResize")
    {
        mWindow->StopResize();
		retval = CefV8Value::CreateNull();
		return true;            
    }
    else if (name == "show")
    {
		if (arguments.size() == 1)
		{
			CefRefPtr<CefV8Value> showWindow = arguments[0];
			bool show = showWindow->GetBoolValue();
            mWindow->Show(show);
		}
		retval = CefV8Value::CreateNull();
		return true;            
    }
    else if (name == "close")
    {
        mWindow->Close();
		retval = CefV8Value::CreateNull();
		return true;            
    }
    else if (name == "setSize")
    {
        if (arguments.size() == 2)
        {
            int width = arguments[0]->GetIntValue();
            int height = arguments[1]->GetIntValue();
            mWindow->SetSize(width, height);
            retval = CefV8Value::CreateNull();
            return true;            
        }
    }
    else if (name == "move")
    {
        if (arguments.size() == 2)
        {
            int x = arguments[0]->GetIntValue();
            int y = arguments[1]->GetIntValue();
            mWindow->SetPos(x, y);
            retval = CefV8Value::CreateNull();
            return true;            
        }
    }
    else if (name == "screenSize")
    {
        int width, height;
        mWindow->GetScreenSize(width, height);
        CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(NULL, NULL);
        obj->SetValue("width", CefV8Value::CreateInt(width), V8_PROPERTY_ATTRIBUTE_READONLY);
        obj->SetValue("height", CefV8Value::CreateInt(height), V8_PROPERTY_ATTRIBUTE_READONLY);
        retval = obj;
        return true;        
    }
    else if (name == "createWindow")
    {
        if (arguments.size() == 1)
        {
            std::string url = arguments[0]->GetStringValue().ToString();
            CSLogDebug("createWindow(%s)", url.c_str());
            CSWindow *window = new CSWindow(url.c_str());
            window->Show(false);
            retval = CefV8Value::CreateNull();
            return true;            
        }
    }
    else if (name == "menu")
    {
        if (arguments.size() == 1)
        {
            retval = CSJsMenu::CreateMenu(arguments[0]->GetStringValue());
            return true;
        }
    }
    else if (name == "mainMenu")
    {
        retval = CSJsMenu::GetMainMenu();
        return true;
    }
    
    return false;
}