Home | History | Annotate | Download | only in js
      1 /*
      2  *  Copyright (C) 2001 Peter Kelly (pmk (at) post.com)
      3  *  Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
      4  *
      5  *  This library is free software; you can redistribute it and/or
      6  *  modify it under the terms of the GNU Lesser General Public
      7  *  License as published by the Free Software Foundation; either
      8  *  version 2 of the License, or (at your option) any later version.
      9  *
     10  *  This library is distributed in the hope that it will be useful,
     11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  *  Lesser General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU Lesser General Public
     16  *  License along with this library; if not, write to the Free Software
     17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18  */
     19 
     20 #include "config.h"
     21 #include "JSNodeFilterCondition.h"
     22 
     23 #include "JSNode.h"
     24 #include "JSNodeFilter.h"
     25 #include "NodeFilter.h"
     26 #include <runtime/JSLock.h>
     27 
     28 namespace WebCore {
     29 
     30 using namespace JSC;
     31 
     32 ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition);
     33 
     34 JSNodeFilterCondition::JSNodeFilterCondition(JSValue filter)
     35     : m_filter(filter)
     36 {
     37 }
     38 
     39 void JSNodeFilterCondition::markAggregate(MarkStack& markStack)
     40 {
     41     markStack.append(m_filter);
     42 }
     43 
     44 short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) const
     45 {
     46     JSLock lock(SilenceAssertionsOnly);
     47 
     48     CallData callData;
     49     CallType callType = m_filter.getCallData(callData);
     50     if (callType == CallTypeNone)
     51         return NodeFilter::FILTER_ACCEPT;
     52 
     53    // The exec argument here should only be null if this was called from a
     54    // non-JavaScript language, and this is a JavaScript filter, and the document
     55    // in question is not associated with the frame. In that case, we're going to
     56    // behave incorrectly, and just reject nodes instead of calling the filter function.
     57    // To fix that we'd need to come up with a way to find a suitable JavaScript
     58    // execution context for the filter function to run in.
     59     if (!exec)
     60         return NodeFilter::FILTER_REJECT;
     61 
     62     MarkedArgumentBuffer args;
     63     // FIXME: The node should have the prototype chain that came from its document, not
     64     // whatever prototype chain might be on the window this filter came from. Bug 27662
     65     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), filterNode));
     66     if (exec->hadException())
     67         return NodeFilter::FILTER_REJECT;
     68 
     69     JSValue result = JSC::call(exec, m_filter, callType, callData, m_filter, args);
     70     if (exec->hadException())
     71         return NodeFilter::FILTER_REJECT;
     72 
     73     int intResult = result.toInt32(exec);
     74     if (exec->hadException())
     75         return NodeFilter::FILTER_REJECT;
     76 
     77     return intResult;
     78 }
     79 
     80 } // namespace WebCore
     81