Не уверен, что кто-либо сталкивался и будут мнения, но попытка как говорится...
Вобщем за любые предложения благодарен.
Затея в том, что нужно сделать так, чтобы 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-мя этими исходниками для сравнения.