Russian Qt Forum
Апрель 20, 2024, 03:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Изменение QtWebKit  (Прочитано 4541 раз)
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« : Июнь 09, 2010, 13:58 »

Не уверен, что кто-либо сталкивался и будут мнения, но попытка как говорится...
Вобщем за любые предложения благодарен.

Затея в том, что нужно сделать так, чтобы readonly-свойства некоторых объектов яваскрипта были доступны и на запись, например такое св-во как height объекта screen.
Т.е. если, допустим, написать:
Код
Javascript
screen.height = 555;
document.write("screen.height: " + screen.height);
 
то выведется всё равно истинная высота экрана, а не 555. А надо сделать чтобы вывело именно 555.

Для всех объектов, где эти свойства также доступны на запись, принцип кода следующий (на примере HTMLElement).
Есть .h и .cpp-файл объекта HTMLElement (он базовый, его наследуют много DOM-объектов, например DIV).
В JSHTMLElement.h есть одна из функций (опять же, как пример, этих функций много), которая вызывается при выполнении такого кода яваскрипта:
Код
Javascript
document.getElementById("xxx").innerHTML = "<b>text</b>";
 
где "xxx" это id, например, DIV'а.

Функция с++, которая выполняет собственно присвоение (декларация в JSHTMLElement.h):
Код
C++ (Qt)
void setJSHTMLElementInnerHTML(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);
 

Её инициализация в файле JSHTMLElement.cpp:
Код
C++ (Qt)
void setJSHTMLElementInnerHTML(ExecState* exec, JSObject* thisObject, JSValue value)
{
   JSHTMLElement* castedThisObj = static_cast<JSHTMLElement*>(thisObject);
   HTMLElement* imp = static_cast<HTMLElement*>(castedThisObj->impl());
   ExceptionCode ec = 0;
   imp->setInnerHTML(valueToStringWithNullCheck(exec, value), ec);
   setDOMException(exec, ec);
  //вместо этого тут можно присвоить ему любой текст
}
 

Чтобы "innerHTML" знал что он не только для чтения, но и для записи есть специальный шаблон, тоже в JSHTMLElement.cpp:
Код
C++ (Qt)
static const HashTableValue JSHTMLElementTableValues[16] =
{
...
   { "innerHTML", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLElementInnerHtml), (intptr_t)setJSHTMLElementInnerHtml },
...
};
 

где setJSHTMLElementInnerHtml  - вышеописанная функция.
Если бы "innerHTML" был доступен только для чтения, то код был бы:
Код
C++ (Qt)
static const HashTableValue JSHTMLElementTableValues[16] =
{
...
   { "innerHtml", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLElementInnerHtml), (intptr_t)0 },
...
};
 

коим он и является для "height" объекта screen (первый элемент массива):
Код
C++ (Qt)
static const HashTableValue JSScreenTableValues[9] =
{
   { "height", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenHeight), (intptr_t)0 },
   { "width", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenWidth), (intptr_t)0 },
   { "colorDepth", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenColorDepth), (intptr_t)0 },
   { "pixelDepth", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenPixelDepth), (intptr_t)0 },
   { "availLeft", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenAvailLeft), (intptr_t)0 },
   { "availTop", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenAvailTop), (intptr_t)0 },
   { "availHeight", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenAvailHeight), (intptr_t)0 },
   { "availWidth", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenAvailWidth), (intptr_t)0 },
   { 0, 0, 0, 0 }
}
 
И, что немаловажно, все остальные свойства объекта тоже только для чтения.

Вся интересность в том, что если дописать свои методы для изменения значений свойств в классы где в HashTableValue-массиве уже присутствуют поля у которых доступна возможность изменения, то всё ок. Таким образом, например, добавил свой метод для изменения свойства document.referrer (на самом деле это св-во изначально было только для чтения).
А вот screen.height никак не хочет реагировать на добавленный в этот массив метод. Сборка - нормально, js ошибок тоже не выдаёт, но мой метод после изменения на:
Код
C++ (Qt)
{ "height", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsScreenHeight), (intptr_t)jsSetScreenHeight },
 

(сам метод - jsSetScreenHeight)
всё равно почему-то не вызывается. Не могу найти ещё одну разницу между такими классами как JSScreen (где все поля только на чтение) и JSHTMLElement (где присутствуют поля и только на чтение, и также поля на чтение/запись) кроме задания такого шаблона элементов для HashTableValue-массива.

Вобщем может кто-то знает где есть дока по вебкиту или что-то, что может помоч в вопросе? Находил все эти моменты сам, т.к. в инете ничего подобного не встретил((.
Если кого заинтересовал такой контроль над яваскриптом, то прикрепил архив с 4-мя этими исходниками для сравнения.
« Последнее редактирование: Июнь 12, 2010, 14:46 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #1 : Июнь 10, 2010, 02:39 »

готово, надо было отыскать ещё одну для присвоения нового значения функцию (всего получается 4 шага).
Записан

kubuntu/Win7/x64/NetBeans
BigZ
Гость
« Ответ #2 : Июнь 10, 2010, 09:54 »

Очень возможно, что для height уже где-то зарегистрирован свой внутренний сеттер, поэтому до тебя управление не доходит.
Записан
arvitaly
Гость
« Ответ #3 : Июль 18, 2012, 23:00 »

Цитировать
Таким образом, например, добавил свой метод для изменения свойства document.referrer (на самом деле это св-во изначально было только для чтения).

Покажи, пожалуйста, как
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.157 секунд. Запросов: 22.